diff --git a/mathics/builtin/__init__.py b/mathics/builtin/__init__.py index 25c9e4ee7..abf253fe5 100755 --- a/mathics/builtin/__init__.py +++ b/mathics/builtin/__init__.py @@ -23,7 +23,11 @@ import re from mathics.builtin.base import Builtin -from mathics.eval.builtin import add_builtins, import_builtins, name_is_builtin_symbol +from mathics.core.load_builtin import ( + add_builtins, + import_builtins, + name_is_builtin_symbol, +) from mathics.settings import ENABLE_FILES_MODULE # Get a list of files in this directory. We'll exclude from the start diff --git a/mathics/core/definitions.py b/mathics/core/definitions.py index 64de0cb91..93643fcc0 100644 --- a/mathics/core/definitions.py +++ b/mathics/core/definitions.py @@ -15,9 +15,9 @@ 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.symbols import Atom, Symbol, strip_context from mathics.core.systemsymbols import SymbolGet -from mathics.eval.builtin import definition_contribute type_compiled_pattern = type(re.compile("a.a")) diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py index c5132fa77..d2b8aee3b 100644 --- a/mathics/docpipeline.py +++ b/mathics/docpipeline.py @@ -25,9 +25,9 @@ from mathics.builtin import builtins_by_module from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation, Output +from mathics.core.load_builtin import builtins_dict from mathics.core.parser import MathicsSingleLineFeeder from mathics.doc.common_doc import MathicsMainDocumentation -from mathics.eval.builtin import builtins_dict from mathics.eval.pymathics import PyMathicsLoadException, eval_LoadModule from mathics.timing import show_lru_cache_statistics diff --git a/mathics/eval/builtin.py b/mathics/eval/builtin.py deleted file mode 100755 index 3766f5bb4..000000000 --- a/mathics/eval/builtin.py +++ /dev/null @@ -1,167 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Code around loading Mathics3 Builtin Functions and Variables. - -This code loads the top-level definition of a Mathics3 -Builtin, and attributes that have not been segregated elsewhere such -as has been done for one of the other modules listed above. -""" - -import importlib -import inspect -from typing import Optional - -from mathics.core.pattern import pattern_objects -from mathics.core.symbols import Symbol -from mathics.eval.makeboxes import builtins_precedence - -_builtins = {} - -# The fact that are importing inside here, suggests add_builtins -# should get moved elsewhere. -def add_builtins(new_builtins): - from mathics.builtin.base import ( - Operator, - PatternObject, - SympyObject, - mathics_to_python, - ) - from mathics.core.convert.sympy import mathics_to_sympy, sympy_to_mathics - - for _, 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[Symbol(name)] = builtin.precedence - if isinstance(builtin, PatternObject): - pattern_objects[name] = builtin.__class__ - _builtins.update(dict(new_builtins)) - - -def builtins_dict(builtins_by_module): - return { - builtin.get_name(): builtin - for _, builtins in builtins_by_module.items() - for builtin in builtins - } - - -def definition_contribute(definitions): - # let MakeBoxes contribute first - _builtins["System`MakeBoxes"].contribute(definitions) - for name, item in _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) - - -# TODO: When we drop Python 3.7, -# module_names can be a List[Literal] -def import_builtins(modules: list, module_names: list, submodule_name=None) -> None: - """ - Imports the list of Mathics3 Built-in modules so that inside - Mathics3 Builtin Functions, like Plus[], List[] are defined. - """ - - def import_module(module_name: str, import_name: str): - try: - module = importlib.import_module(import_name) - except Exception as e: - print(e) - print(f" Not able to load {module_name}. Check your installation.") - print(f" mathics.builtin loads from {__file__[:-11]}") - return None - - if module: - modules.append(module) - - if submodule_name: - import_module(submodule_name, f"mathics.builtin.{submodule_name}") - - for module_name in module_names: - import_name = ( - f"mathics.builtin.{submodule_name}.{module_name}" - if submodule_name - else f"mathics.builtin.{module_name}" - ) - import_module(module_name, import_name) - - -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 - - # Skip those builtins defined in or imported from another module. - - # rocky: I think this is a code smell. It doesn't feel like - # we should have to do this if things are organized and modularized - # builtins and use less custom code. - # mmatera reports that we need this because of the interaction of - # * the custom Mathics3 loading/importing mechanism, - # * the builtin module hierarchy, e.g. mathics.builtin.arithmetic - # nested under mathics.builtin, and - # * our custom doc/doctest and possibly custom checking system - - # Mathics3 modules modules, however, right now import all builtin modules from - # __init__ - # Note Mathics3 modules do not support buitin hierarchies, e.g. - # pymathics.graph.parametric is allowed but not pymathics.graph.parametric.xxx. - # This too has to do with the custom doc/doctest that is currently used. - - if inspect.getmodule( - module_object - ) is not module and not module.__name__.startswith("pymathics."): - 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.") - or module_object.__module__.startswith("pymathics.") - ): - return None - - from mathics.builtin.base import Builtin - - # 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 diff --git a/mathics/eval/pymathics.py b/mathics/eval/pymathics.py index 448d761a6..e4b68ccc4 100644 --- a/mathics/eval/pymathics.py +++ b/mathics/eval/pymathics.py @@ -9,7 +9,7 @@ from mathics.builtin import builtins_by_module from mathics.builtin.base import Builtin from mathics.core.definitions import Definitions -from mathics.eval.builtin import name_is_builtin_symbol +from mathics.core.load_builtin import name_is_builtin_symbol # The below set and dictionary are used in document generation # for Pymathics modules.