From de81a34fda6e94419631f61890126a9149062780 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 4 Dec 2022 06:26:24 -0500 Subject: [PATCH] builtin.system_init -> core.system_init Move system initialization module out of mathics.builtin. (Similar to PR #639) This also removes the need for Python to "partially initialize" mathics.builtin since it doesn't import one of its children --- .../symbolic_logic/gries_schneider/test_gs.py | 2 +- mathics/builtin/__init__.py | 2 +- mathics/builtin/system_init.py | 208 ------------------ mathics/core/definitions.py | 2 +- mathics/core/pymathics.py | 2 +- mathics/doc/common_doc.py | 6 +- mathics/docpipeline.py | 2 +- mathics/format/mathml.py | 2 +- mathics/main.py | 2 +- mathics/session.py | 2 +- .../test_duplicate_builtins.py | 2 +- 11 files changed, 13 insertions(+), 219 deletions(-) delete mode 100644 mathics/builtin/system_init.py diff --git a/examples/symbolic_logic/gries_schneider/test_gs.py b/examples/symbolic_logic/gries_schneider/test_gs.py index 44cc4ede6..9bd5b765a 100644 --- a/examples/symbolic_logic/gries_schneider/test_gs.py +++ b/examples/symbolic_logic/gries_schneider/test_gs.py @@ -2,10 +2,10 @@ # -*- coding: utf-8 -*- -from mathics.builtin.system_init import initialize_system from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation from mathics.core.parser import MathicsSingleLineFeeder, parse +from mathics.core.system_init import initialize_system initialize_system() definitions = Definitions(add_builtin=True) diff --git a/mathics/builtin/__init__.py b/mathics/builtin/__init__.py index 69085d7f4..289e479ea 100755 --- a/mathics/builtin/__init__.py +++ b/mathics/builtin/__init__.py @@ -32,8 +32,8 @@ SympyObject, mathics_to_python, ) -from mathics.builtin.system_init import get_builtin_pyfiles, name_is_builtin_symbol from mathics.core.pattern import pattern_objects +from mathics.core.system_init import get_builtin_pyfiles, name_is_builtin_symbol from mathics.settings import ENABLE_FILES_MODULE __py_files__ = get_builtin_pyfiles() diff --git a/mathics/builtin/system_init.py b/mathics/builtin/system_init.py deleted file mode 100644 index ecebb4a5b..000000000 --- a/mathics/builtin/system_init.py +++ /dev/null @@ -1,208 +0,0 @@ -""" -One-time initialization of Mathics module loading, and creation of built-in functions. -""" - -import glob -import inspect -import os.path as osp -from typing import Optional - -from mathics.builtin.base import ( - Builtin, - Operator, - PatternObject, - SympyObject, - mathics_to_python, -) - -from mathics.core.pattern import pattern_objects - -builtins_precedence = {} -mathics_to_sympy = {} # here we have: name -> sympy object -sympy_to_mathics = {} - -# builtins_by_module maps a full module name, e.g. "mathics.builtin.evaluation" to a -# list of Builtin classes. -builtins_by_module = {} -builtins_list = [] -builtins_precedence = {} - -system_builtins = {} - - -def add_builtins(new_builtins): - for var_name, builtin in new_builtins: - name = builtin.get_name() - if hasattr(builtin, "python_equivalent"): - # print("XXX0", builtin.python_equivalent) - mathics_to_python[name] = builtin.python_equivalent - - if isinstance(builtin, SympyObject): - mathics_to_sympy[name] = builtin - for sympy_name in builtin.get_sympy_names(): - # print("XXX1", sympy_name) - sympy_to_mathics[sympy_name] = builtin - if isinstance(builtin, Operator): - builtins_precedence[name] = builtin.precedence - if isinstance(builtin, PatternObject): - pattern_objects[name] = builtin.__class__ - system_builtins.update(dict(new_builtins)) - - -def builtins_dict(): - return { - builtin.get_name(): builtin - for modname, builtins in builtins_by_module.items() - for builtin in builtins - } - - -def contribute(definitions): - # let MakeBoxes contribute first - system_builtins["System`MakeBoxes"].contribute(definitions) - for name, item in system_builtins.items(): - if name != "System`MakeBoxes": - item.contribute(definitions) - - from mathics.core.definitions import Definition - from mathics.core.expression import ensure_context - from mathics.core.parser import all_operator_names - - # All builtins are loaded. Create dummy builtin definitions for - # any remaining operators that don't have them. This allows - # operators like \[Cup] to behave correctly. - for operator in all_operator_names: - if not definitions.have_definition(ensure_context(operator)): - op = ensure_context(operator) - definitions.builtin[op] = Definition(name=op) - - -def create_builtins_by_module(): - from mathics.builtin import modules - - for module in modules: - builtins_by_module[module.__name__] = [] - module_vars = dir(module) - - for name in module_vars: - builtin_class = name_is_builtin_symbol(module, name) - if builtin_class is not None: - instance = builtin_class(expression=False) - - if isinstance(instance, Builtin): - # This set the default context for symbols in mathics.builtins - if not type(instance).context: - type(instance).context = "System`" - assert sanity_check( - builtin_class, module - ), f"In {module.__name__} Builtin <<{builtin_class.__name__}>> did not pass the sanity check." - - builtins_list.append((instance.get_name(), instance)) - builtins_by_module[module.__name__].append(instance) - add_builtins(builtins_list) - - -def get_builtin_pyfiles() -> tuple: - """ - Return a list of files in this directory. We'll exclude from the start - files with leading characters we don't want like __init__ with its leading underscore. - """ - return tuple( - osp.basename(f[0:-3]) - for f in glob.glob(osp.join(osp.dirname(__file__), "[a-z]*.py")) - ) - - -display_operators_set = set() - -# TODO: after doing more, e.g. moving Builtin class processing, -# consider adding an administrative routine to write definitions in -# Python Pickle format (or something suitable. Then we can add a flag -# here to read this in which might be faster. -# -def initialize_system(): - """ - One-time Builtin initialization. - Not much here but more may be added. - """ - create_builtins_by_module() - for modname, builtins in builtins_by_module.items(): - for builtin in builtins: - # name = builtin.get_name() - operator = builtin.get_operator_display() - if operator is not None: - display_operators_set.add(operator) - - -def name_is_builtin_symbol(module, name: str) -> Optional[type]: - """ - Checks if ``name`` should be added to definitions, and return - its associated Builtin class. - - Return ``None`` if the name should not get added to definitions. - """ - if name.startswith("_"): - return None - - module_object = getattr(module, name) - - # Look only at Class objects. - if not inspect.isclass(module_object): - return None - - # FIXME: tests involving module_object.__module__ are fragile and - # Python implementation specific. Figure out how to do this - # via the inspect module which is not implementation specific. - - # Skip those builtins defined in or imported from another module. - if module_object.__module__ != module.__name__: - return None - - # Skip objects in module mathics.builtin.base. - if module_object.__module__ == "mathics.builtin.base": - return None - - # Skip those builtins that are not submodules of mathics.builtin. - if not module_object.__module__.startswith("mathics.builtin."): - return None - - # If it is not a subclass of Builtin, skip it. - if not issubclass(module_object, Builtin): - return None - - # Skip Builtin classes that were explicitly marked for skipping. - if module_object in getattr(module, "DOES_NOT_ADD_BUILTIN_DEFINITION", []): - return None - return module_object - - -# FIXME: Checking can be done as an outside -# utility program. Think for example, "flake8", "black", or "isort". - -# Set this to True to print all the builtins that do not have -# a summary_text. In the future, we can set this to True -# and raise an error if a new builtin is added without -# this property or if it does not fulfill some other conditions. -RUN_SANITY_TEST = False - - -def sanity_check(cls, module): - """ - Look for Builtin classes that do not have a ``summary_text`` - and do not have a class attribute "context" set to "Internal" - """ - if not RUN_SANITY_TEST: - return True - - if not ( - hasattr(cls, "summary_text") - or (hasattr(cls, "context") and cls.context == "Internal") - ): - print( - "In ", - module.__name__, - cls.__name__, - " does not have a summary_text.", - ) - return False - return True diff --git a/mathics/core/definitions.py b/mathics/core/definitions.py index e286ea81a..cda4eaca3 100644 --- a/mathics/core/definitions.py +++ b/mathics/core/definitions.py @@ -21,6 +21,7 @@ Symbol, strip_context, ) +from mathics.core.system_init import contribute from mathics.core.systemsymbols import SymbolGet from mathics_scanner.tokeniser import full_names_pattern @@ -130,7 +131,6 @@ def __init__( if add_builtin: from mathics.builtin import modules - from mathics.builtin.system_init import contribute from mathics.settings import ROOT_DIR loaded = False diff --git a/mathics/core/pymathics.py b/mathics/core/pymathics.py index aa499bc8e..293bfa69f 100644 --- a/mathics/core/pymathics.py +++ b/mathics/core/pymathics.py @@ -7,8 +7,8 @@ import sys -from mathics.builtin.system_init import builtins_by_module, name_is_builtin_symbol from mathics.core.evaluation import Evaluation +from mathics.core.system_init import builtins_by_module, name_is_builtin_symbol # Tis dict # Probably this do not belong here. diff --git a/mathics/doc/common_doc.py b/mathics/doc/common_doc.py index ed86408a1..5431bfe24 100644 --- a/mathics/doc/common_doc.py +++ b/mathics/doc/common_doc.py @@ -34,11 +34,14 @@ from types import ModuleType from typing import Callable +import mathics.core as core from mathics import builtin from mathics import settings from mathics.builtin.base import check_requires_list from mathics.core.evaluation import Message, Print from mathics.core.util import IS_PYPY +from mathics.core.system_init import name_is_builtin_symbol + from mathics.doc.utils import slugify # These regular expressions pull out information from docstring or text in a file. @@ -830,7 +833,7 @@ def __init__(self, want_sorting=False): ( "Reference of Built-in Symbols", builtin.modules, - builtin.system_init.builtins_by_module, + core.system_init.builtins_by_module, True, ) ]: # nopep8 @@ -1088,7 +1091,6 @@ def __init__(self, module=None): # Load the dictionary of mathics symbols defined in the module self.symbols = {} from mathics.builtin.base import Builtin - from mathics.builtin.system_init import name_is_builtin_symbol print("loading symbols") for name in dir(self.pymathicsmodule): diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py index df3fe029f..346f46f73 100644 --- a/mathics/docpipeline.py +++ b/mathics/docpipeline.py @@ -24,7 +24,7 @@ from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation, Output from mathics.core.parser import MathicsSingleLineFeeder -from mathics.builtin.system_init import builtins_dict, initialize_system +from mathics.core.system_init import builtins_dict, initialize_system from mathics import version_string from mathics import settings diff --git a/mathics/format/mathml.py b/mathics/format/mathml.py index a95d8b773..dcf046b93 100644 --- a/mathics/format/mathml.py +++ b/mathics/format/mathml.py @@ -21,7 +21,6 @@ ) from mathics.builtin.box.graphics import GraphicsBox from mathics.builtin.box.graphics3d import Graphics3DBox -from mathics.builtin.system_init import display_operators_set as operators from mathics.core.atoms import String @@ -33,6 +32,7 @@ ) from mathics.core.parser import is_symbol_name from mathics.core.symbols import SymbolTrue +from mathics.core.system_init import display_operators_set as operators def encode_mathml(text: str) -> str: diff --git a/mathics/main.py b/mathics/main.py index e49f66e75..e5b6668e6 100755 --- a/mathics/main.py +++ b/mathics/main.py @@ -14,7 +14,6 @@ from mathics import settings from mathics import version_string, license_string, __version__ from mathics.builtin.trace import TraceBuiltins, traced_do_replace -from mathics.builtin.system_init import initialize_system from mathics.core.atoms import String from mathics.core.definitions import autoload_files, Definitions, Symbol from mathics.core.evaluation import Evaluation, Output @@ -24,6 +23,7 @@ from mathics.core.rules import BuiltinRule from mathics.core.symbols import strip_context, SymbolNull from mathics.core.streams import stream_manager +from mathics.core.system_init import initialize_system from mathics.timing import show_lru_cache_statistics diff --git a/mathics/session.py b/mathics/session.py index 35962c026..ca8c2e845 100644 --- a/mathics/session.py +++ b/mathics/session.py @@ -12,11 +12,11 @@ import os.path as osp from typing import Optional -from mathics.builtin.system_init import initialize_system from mathics.core.definitions import autoload_files from mathics.core.parser import parse, MathicsSingleLineFeeder from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation +from mathics.core.system_init import initialize_system import mathics.settings diff --git a/test/consistency-and-style/test_duplicate_builtins.py b/test/consistency-and-style/test_duplicate_builtins.py index dcbb49bf0..de6faff9a 100644 --- a/test/consistency-and-style/test_duplicate_builtins.py +++ b/test/consistency-and-style/test_duplicate_builtins.py @@ -8,7 +8,7 @@ import os from mathics.builtin import modules from mathics.builtin.base import Builtin -from mathics.builtin.system_init import name_is_builtin_symbol +from mathics.core.system_init import name_is_builtin_symbol @pytest.mark.skipif(