From 72488a4d418c9047d2901c2adad492d533bc1afe Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 15 Jul 2023 13:41:51 -0400 Subject: [PATCH] Move builtin loading code entirely out of __init__ ... YAY! This paves the way for further improvements. --- admin-tools/build_and_check_manifest.py | 9 ++++- .../symbolic_logic/gries_schneider/test_gs.py | 2 ++ mathics/builtin/__init__.py | 35 ------------------ mathics/core/definitions.py | 5 ++- mathics/core/load_builtin.py | 36 +++++++++++++++++++ mathics/doc/common_doc.py | 9 +++-- mathics/docpipeline.py | 9 +++-- mathics/main.py | 3 ++ mathics/version.py | 2 +- .../test_duplicate_builtins.py | 12 ++++--- test/helper.py | 3 ++ 11 files changed, 75 insertions(+), 50 deletions(-) diff --git a/admin-tools/build_and_check_manifest.py b/admin-tools/build_and_check_manifest.py index 9057a0f34..0feb64af9 100755 --- a/admin-tools/build_and_check_manifest.py +++ b/admin-tools/build_and_check_manifest.py @@ -2,7 +2,14 @@ import sys -from mathics.builtin import Builtin, modules, name_is_builtin_symbol +from mathics.builtin.base import Builtin +from mathics.core.load_builtin import ( + import_and_load_builtins, + modules, + name_is_builtin_symbol, +) + +import_and_load_builtins() def generate_available_builtins_names(): diff --git a/examples/symbolic_logic/gries_schneider/test_gs.py b/examples/symbolic_logic/gries_schneider/test_gs.py index 7212ec8ee..19cd96d03 100644 --- a/examples/symbolic_logic/gries_schneider/test_gs.py +++ b/examples/symbolic_logic/gries_schneider/test_gs.py @@ -4,8 +4,10 @@ from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation +from mathics.core.load_builtin import import_and_load_builtins from mathics.core.parser import MathicsSingleLineFeeder, parse +import_and_load_builtins() definitions = Definitions(add_builtin=True) for i in range(0, 4): diff --git a/mathics/builtin/__init__.py b/mathics/builtin/__init__.py index 946d024ba..efb232604 100755 --- a/mathics/builtin/__init__.py +++ b/mathics/builtin/__init__.py @@ -15,38 +15,3 @@ builtin class such as the Builtin's Attributes, its Information text, among other things. """ - -import os -import os.path as osp - -from mathics.core.load_builtin import ( - add_builtins_from_builtin_modules, - get_module_names, - import_builtin_subdirectories, - import_builtins, - initialize_display_operators_set, -) -from mathics.settings import ENABLE_FILES_MODULE - -# Get import modules in this directory of Python modules that contain -# Mathics3 Builtin class definitions. - -builtin_path = osp.dirname(__file__) -exclude_files = {"codetables", "base"} -module_names = get_module_names(builtin_path, exclude_files) -modules = [] -import_builtins(module_names, modules) - -# Get import modules in subdirectories of this directory of Python -# modules that contain Mathics3 Builtin class definitions. - -# The files_io module handles local file access, reading and writing.. -# In some sandboxed settings, such as running Mathics from as a remote -# server, we disallow local file access. -disable_file_module_names = set() if ENABLE_FILES_MODULE else {"files_io"} - -subdirectories = next(os.walk(builtin_path))[1] -import_builtin_subdirectories(subdirectories, disable_file_module_names, modules) - -add_builtins_from_builtin_modules(modules) -initialize_display_operators_set() diff --git a/mathics/core/definitions.py b/mathics/core/definitions.py index 93643fcc0..8213879e6 100644 --- a/mathics/core/definitions.py +++ b/mathics/core/definitions.py @@ -15,9 +15,10 @@ from mathics.core.convert.expression import to_mathics_list from mathics.core.element import fully_qualified_symbol_name from mathics.core.expression import Expression -from mathics.core.load_builtin import definition_contribute +from mathics.core.load_builtin import definition_contribute, modules from mathics.core.symbols import Atom, Symbol, strip_context from mathics.core.systemsymbols import SymbolGet +from mathics.settings import ROOT_DIR type_compiled_pattern = type(re.compile("a.a")) @@ -138,8 +139,6 @@ def __init__( self.timing_trace_evaluation = False if add_builtin: - from mathics.builtin import modules - from mathics.settings import ROOT_DIR loaded = False if builtin_filename is not None: diff --git a/mathics/core/load_builtin.py b/mathics/core/load_builtin.py index 376412412..a40399b84 100755 --- a/mathics/core/load_builtin.py +++ b/mathics/core/load_builtin.py @@ -8,6 +8,7 @@ import importlib import inspect +import os import os.path as osp import pkgutil from glob import glob @@ -16,6 +17,11 @@ from mathics.core.pattern import pattern_objects from mathics.core.symbols import Symbol from mathics.eval.makeboxes import builtins_precedence +from mathics.settings import ENABLE_FILES_MODULE + +# List of Mathics3 Builtin modules. +# This is initialized via below import_builtins modules +modules = [] _builtins = {} builtins_by_module = {} @@ -110,6 +116,36 @@ def get_module_names(builtin_path: str, exclude_files: set) -> list: return [f for f in py_files if f not in exclude_files] +def import_and_load_builtins(): + """ + Imports Builtin modules in mathics.builtin and add rules, and definitions from that. + """ + builtin_path = osp.join( + osp.dirname( + __file__, + ), + "..", + "builtin", + ) + exclude_files = {"codetables", "base"} + module_names = get_module_names(builtin_path, exclude_files) + import_builtins(module_names, modules) + + # Get import modules in subdirectories of this directory of Python + # modules that contain Mathics3 Builtin class definitions. + + # The files_io module handles local file access, reading and writing.. + # In some sandboxed settings, such as running Mathics from as a remote + # server, we disallow local file access. + disable_file_module_names = set() if ENABLE_FILES_MODULE else {"files_io"} + + subdirectories = next(os.walk(builtin_path))[1] + import_builtin_subdirectories(subdirectories, disable_file_module_names, modules) + + add_builtins_from_builtin_modules(modules) + initialize_display_operators_set() + + # TODO: When we drop Python 3.7, # module_names can be a List[Literal] def import_builtins( diff --git a/mathics/doc/common_doc.py b/mathics/doc/common_doc.py index f6c1a169e..a5e4e59a5 100644 --- a/mathics/doc/common_doc.py +++ b/mathics/doc/common_doc.py @@ -31,10 +31,13 @@ from types import ModuleType from typing import Callable -from mathics import builtin, settings +from mathics import settings from mathics.builtin.base import check_requires_list from mathics.core.evaluation import Message, Print -from mathics.core.load_builtin import builtins_by_module as global_builtins_by_module +from mathics.core.load_builtin import ( + builtins_by_module as global_builtins_by_module, + modules as mathics3_builtin_modules, +) from mathics.core.util import IS_PYPY from mathics.doc.utils import slugify from mathics.eval.pymathics import pymathics_builtins_by_module, pymathics_modules @@ -635,7 +638,7 @@ def gather_doctest_data(self): for title, modules, builtins_by_module, start in [ ( "Reference of Built-in Symbols", - builtin.modules, + mathics3_builtin_modules, global_builtins_by_module, True, ) diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py index a3be9bef1..b8d6f4cd4 100644 --- a/mathics/docpipeline.py +++ b/mathics/docpipeline.py @@ -24,7 +24,11 @@ from mathics import settings, version_string from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation, Output -from mathics.core.load_builtin import builtins_by_module, builtins_dict +from mathics.core.load_builtin import ( + builtins_by_module, + builtins_dict, + import_and_load_builtins, +) from mathics.core.parser import MathicsSingleLineFeeder from mathics.doc.common_doc import MathicsMainDocumentation from mathics.eval.pymathics import PyMathicsLoadException, eval_LoadModule @@ -177,7 +181,6 @@ def test_tests( max_tests=MAX_TESTS, excludes=[], ): - # For consistency set the character encoding ASCII which is # the lowest common denominator available on all systems. mathics.settings.SYSTEM_CHARACTER_ENCODING = "ASCII" @@ -487,6 +490,8 @@ def main(): global definitions global logfile global check_partial_elapsed_time + + import_and_load_builtins() definitions = Definitions(add_builtin=True) parser = ArgumentParser(description="Mathics test suite.", add_help=False) diff --git a/mathics/main.py b/mathics/main.py index 3d220a8e3..067be1bf4 100755 --- a/mathics/main.py +++ b/mathics/main.py @@ -24,6 +24,7 @@ from mathics.core.definitions import Definitions, Symbol, autoload_files from mathics.core.evaluation import Evaluation, Output from mathics.core.expression import Expression +from mathics.core.load_builtin import import_and_load_builtins from mathics.core.parser import MathicsFileLineFeeder, MathicsLineFeeder from mathics.core.read import channel_to_stream from mathics.core.rules import BuiltinRule @@ -31,6 +32,8 @@ from mathics.core.symbols import SymbolNull, strip_context from mathics.timing import show_lru_cache_statistics +import_and_load_builtins() + def get_srcdir(): filename = osp.normcase(osp.dirname(osp.abspath(__file__))) diff --git a/mathics/version.py b/mathics/version.py index 11bfc1b45..c36ca72bb 100644 --- a/mathics/version.py +++ b/mathics/version.py @@ -5,4 +5,4 @@ # well as importing into Python. That's why there is no # space around "=" below. # fmt: off -__version__="6.0.2dev0" # noqa +__version__="6.1.0dev0" # noqa diff --git a/test/consistency-and-style/test_duplicate_builtins.py b/test/consistency-and-style/test_duplicate_builtins.py index 2e2a0dec8..688310d4d 100644 --- a/test/consistency-and-style/test_duplicate_builtins.py +++ b/test/consistency-and-style/test_duplicate_builtins.py @@ -8,9 +8,8 @@ import pytest -from mathics.builtin import modules from mathics.builtin.base import Builtin -from mathics.core.load_builtin import name_is_builtin_symbol +from mathics.core.load_builtin import modules, name_is_builtin_symbol @pytest.mark.skipif( @@ -33,15 +32,18 @@ def test_check_duplicated(): """ assert ( builtins_by_name.get(name, None) is None - ), f"{name} defined in {module} already defined in {builtins_by_name[name]}." + ), f"{name} defined in {module} already defined in " + f{builtins_by_name[name]}." """ # if builtins_by_name.get(name, None) is not None: # print( - # f"\n{name} defined in {module} already defined in {builtins_by_name[name]}." + # (f"\n{name} defined in {module} already defined in + # f{builtins_by_name[name]}.") # ) # msg = ( # msg - # + f"\n{name} defined in {module} already defined in {builtins_by_name[name]}." + # + (f"\n{name} defined in {module} already defined in " + # {builtins_by_name[name]}.") # ) builtins_by_name[name] = module assert msg == "", msg diff --git a/test/helper.py b/test/helper.py index 025dd3ca4..fa7b87d47 100644 --- a/test/helper.py +++ b/test/helper.py @@ -2,8 +2,11 @@ import time from typing import Optional +from mathics.core.load_builtin import import_and_load_builtins from mathics.session import MathicsSession +import_and_load_builtins() + # Set up a Mathics session with definitions. # For consistency set the character encoding ASCII which is # the lowest common denominator available on all systems.