From 530e147f2956b5a84b20942aeedb1ce33598f653 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 20 Nov 2022 09:47:59 -0500 Subject: [PATCH 1/9] Move code out of definitions This moves builtin-creation out of mathics.builtin and core.definitions and into a new module. I thing this is the last step before we actually move builtin creation of the Definitions initialization and into some one-time code. --- mathics/builtin/__init__.py | 29 +++-------------- mathics/builtin/system_init.py | 57 ++++++++++++++++++++++++++++++++++ mathics/core/definitions.py | 35 +++++---------------- mathics/main.py | 3 +- mathics/session.py | 2 +- 5 files changed, 71 insertions(+), 55 deletions(-) create mode 100644 mathics/builtin/system_init.py diff --git a/mathics/builtin/__init__.py b/mathics/builtin/__init__.py index d9d3cfbb4..5500cf970 100755 --- a/mathics/builtin/__init__.py +++ b/mathics/builtin/__init__.py @@ -31,6 +31,9 @@ for f in glob.glob(osp.join(osp.dirname(__file__), "[a-z]*.py")) ] +system_builtins_dict = {} +builtins_by_module = {} + def add_builtins(new_builtins): for var_name, builtin in new_builtins: @@ -48,7 +51,7 @@ def add_builtins(new_builtins): builtins_precedence[name] = builtin.precedence if isinstance(builtin, PatternObject): pattern_objects[name] = builtin.__class__ - _builtins.update(dict(new_builtins)) + system_builtins_dict.update(dict(new_builtins)) def builtins_dict(): @@ -59,26 +62,6 @@ def builtins_dict(): } -def 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) - - def import_builtins(module_names: List[str], submodule_name=None) -> None: """ Imports the list of Mathics Built-in modules so that inside @@ -162,7 +145,6 @@ def name_is_builtin_symbol(module, name: str) -> Optional[type]: import_builtins(module_names) _builtins_list = [] -builtins_by_module = {} disable_file_module_names = ( [] if ENABLE_FILES_MODULE else ["files_io.files", "files_io.importexport"] @@ -258,9 +240,6 @@ def sanity_check(cls, module): new_builtins = _builtins_list -# FIXME: some magic is going on here.. -_builtins = {} - add_builtins(new_builtins) display_operators_set = set() diff --git a/mathics/builtin/system_init.py b/mathics/builtin/system_init.py new file mode 100644 index 000000000..12dd982cc --- /dev/null +++ b/mathics/builtin/system_init.py @@ -0,0 +1,57 @@ +""" +One-time initialization of Mathics built-in functions. + +Eventually - we are not there yet now. Currently this pulls out parts of the Definition class +and mathics.builtin. +""" +import os +import os.path as osp + +from mathics.core.atoms import String +from mathics.core.evaluation import Evaluation +from mathics.core.expression import Expression +from mathics.core.systemsymbols import SymbolGet + +from mathics.core.expression import ensure_context +from mathics.core.parser import all_operator_names + + +def autoload_files( + defs, root_dir_path: str, autoload_dir: str, block_global_definitions: bool = True +): + + # Load symbols from the autoload folder + for root, dirs, files in os.walk(osp.join(root_dir_path, autoload_dir)): + for path in [osp.join(root, f) for f in files if f.endswith(".m")]: + Expression(SymbolGet, String(path)).evaluate(Evaluation(defs)) + + if block_global_definitions: + # Move any user definitions created by autoloaded files to + # builtins, and clear out the user definitions list. This + # means that any autoloaded definitions become shared + # between users and no longer disappear after a Quit[]. + # + # Autoloads that accidentally define a name in Global` + # could cause confusion, so check for this. + + for name in defs.user: + if name.startswith("Global`"): + raise ValueError("autoload defined %s." % name) + + +def update_builtin_definitions(builtins: dict, definitions): + from mathics.core.definitions import Definition + + # let MakeBoxes contribute first + builtins["System`MakeBoxes"].contribute(definitions) + for name, item in builtins.items(): + if name != "System`MakeBoxes": + item.contribute(definitions) + + # 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) diff --git a/mathics/core/definitions.py b/mathics/core/definitions.py index 65fb7f09e..dc2759c59 100644 --- a/mathics/core/definitions.py +++ b/mathics/core/definitions.py @@ -15,13 +15,11 @@ from mathics.core.attributes import A_NO_ATTRIBUTES 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.symbols import ( Atom, Symbol, strip_context, ) -from mathics.core.systemsymbols import SymbolGet from mathics_scanner.tokeniser import full_names_pattern @@ -51,30 +49,6 @@ def valuesname(name) -> str: return name[7:-6].lower() -def autoload_files( - defs, root_dir_path: str, autoload_dir: str, block_global_definitions: bool = True -): - from mathics.core.evaluation import Evaluation - - # Load symbols from the autoload folder - for root, dirs, files in os.walk(os.path.join(root_dir_path, autoload_dir)): - for path in [os.path.join(root, f) for f in files if f.endswith(".m")]: - Expression(SymbolGet, String(path)).evaluate(Evaluation(defs)) - - if block_global_definitions: - # Move any user definitions created by autoloaded files to - # builtins, and clear out the user definitions list. This - # means that any autoloaded definitions become shared - # between users and no longer disappear after a Quit[]. - # - # Autoloads that accidentally define a name in Global` - # could cause confusion, so check for this. - - for name in defs.user: - if name.startswith("Global`"): - raise ValueError("autoload defined %s." % name) - - class Definitions: """ The state of one instance of the Mathics interpreter is stored in this object. @@ -111,6 +85,11 @@ def __init__( PyMathicsLoadException, load_pymathics_module, ) + from mathics.builtin import system_builtins_dict + from mathics.builtin.system_init import ( + autoload_files, + update_builtin_definitions, + ) # Importing "mathics.format" populates the Symbol of the # PrintForms and OutputForms sets. @@ -129,7 +108,7 @@ def __init__( self.timing_trace_evaluation = False if add_builtin: - from mathics.builtin import modules, contribute + from mathics.builtin import modules from mathics.settings import ROOT_DIR loaded = False @@ -141,7 +120,7 @@ def __init__( self.builtin = pickle.load(builtin_file) loaded = True if not loaded: - contribute(self) + update_builtin_definitions(system_builtins_dict, self) for module in extension_modules: try: load_pymathics_module(self, module) diff --git a/mathics/main.py b/mathics/main.py index 3b90a24f6..9e79545a3 100755 --- a/mathics/main.py +++ b/mathics/main.py @@ -13,9 +13,10 @@ from mathics import settings from mathics import version_string, license_string, __version__ +from mathics.builtin.system_init import autoload_files from mathics.builtin.trace import TraceBuiltins, traced_do_replace from mathics.core.atoms import String -from mathics.core.definitions import autoload_files, Definitions, Symbol +from mathics.core.definitions import Definitions, Symbol from mathics.core.evaluation import Evaluation, Output from mathics.core.expression import Expression from mathics.core.parser import MathicsFileLineFeeder, MathicsLineFeeder diff --git a/mathics/session.py b/mathics/session.py index 88a4957b6..5d4278372 100644 --- a/mathics/session.py +++ b/mathics/session.py @@ -12,7 +12,7 @@ import os.path as osp from typing import Optional -from mathics.core.definitions import autoload_files +from mathics.builtin.system_init import autoload_files from mathics.core.parser import parse, MathicsSingleLineFeeder from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation From da8580c81e671f0a26fbafd4b0c5572cfa05592b Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 20 Nov 2022 10:51:56 -0500 Subject: [PATCH 2/9] Add annotiations to some globals ... and add run pytest setting MATHICS_CHARACTER_ENCODING --- Makefile | 2 +- mathics/builtin/__init__.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index bef14777a..9b2e85a0b 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,7 @@ clean: clean-cython clean-cache #: Run py.test tests. Use environment variable "o" for pytest options pytest: - $(PYTHON) -m pytest $(PYTEST_WORKERS) test $o + MATHICS_CHARACTER_ENCODING="ASCII" $(PYTHON) -m pytest $(PYTEST_WORKERS) test $o #: Run a more extensive pattern-matching test diff --git a/mathics/builtin/__init__.py b/mathics/builtin/__init__.py index 5500cf970..b8ba51021 100755 --- a/mathics/builtin/__init__.py +++ b/mathics/builtin/__init__.py @@ -11,7 +11,7 @@ import os.path as osp import pkgutil import re -from typing import List, Optional +from typing import Dict, List, Optional, Type from mathics.builtin.base import ( Builtin, @@ -31,11 +31,18 @@ for f in glob.glob(osp.join(osp.dirname(__file__), "[a-z]*.py")) ] -system_builtins_dict = {} -builtins_by_module = {} +# system_builtins_dict maps a full builtin name, e.g. "System`EulerPhi" to a Builtin class +system_builtins_dict: Dict[str, Type[Builtin]] = {} +# builtins_by_module maps a full module name, e.g. "mathics.builtin.evaluation" to a +# list of Builtin classes. +builtins_by_module: Dict[str, List[Type[Builtin]]] = {} -def add_builtins(new_builtins): + +def add_builtins(new_builtins: list): + """ + Updates system_builtins_dict to insert new_builtins. + """ for var_name, builtin in new_builtins: name = builtin.get_name() if hasattr(builtin, "python_equivalent"): @@ -233,7 +240,7 @@ def sanity_check(cls, module): _builtins_list.append((instance.get_name(), instance)) builtins_by_module[module.__name__].append(instance) -mathics_to_sympy = {} # here we have: name -> sympy object +mathics_to_sympy: Dict[str, Type[Builtin]] = {} # here we have: name -> sympy object sympy_to_mathics = {} builtins_precedence = {} From 6436065e38ffee69608e5598869a162aed40906a Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 20 Nov 2022 20:44:15 -0500 Subject: [PATCH 3/9] WIP - module load, and builtin create once This isn't working but this is the idea. Another PR will contain some of the independent bugs found in this process --- mathics/builtin/__init__.py | 157 +--------------- mathics/builtin/makeboxes.py | 2 +- mathics/builtin/system_init.py | 168 +++++++++++++++++- mathics/core/convert/sympy.py | 2 +- mathics/core/definitions.py | 122 ++++++------- mathics/core/expression.py | 2 +- mathics/core/pymathics.py | 6 +- mathics/core/rules.py | 4 +- mathics/core/symbols.py | 2 +- mathics/doc/common_doc.py | 4 +- mathics/docpipeline.py | 5 +- mathics/format/mathml.py | 2 +- mathics/main.py | 3 +- .../test_duplicate_builtins.py | 3 +- .../test_summary_text.py | 2 +- test/helper.py | 7 +- 16 files changed, 250 insertions(+), 241 deletions(-) diff --git a/mathics/builtin/__init__.py b/mathics/builtin/__init__.py index b8ba51021..98440022b 100755 --- a/mathics/builtin/__init__.py +++ b/mathics/builtin/__init__.py @@ -7,20 +7,12 @@ import glob import importlib -import inspect import os.path as osp import pkgutil import re -from typing import Dict, List, Optional, Type -from mathics.builtin.base import ( - Builtin, - Operator, - PatternObject, - SympyObject, - mathics_to_python, -) -from mathics.core.pattern import pattern_objects +from typing import List + from mathics.settings import ENABLE_FILES_MODULE from mathics.version import __version__ # noqa used in loading to check consistency. @@ -31,43 +23,6 @@ for f in glob.glob(osp.join(osp.dirname(__file__), "[a-z]*.py")) ] -# system_builtins_dict maps a full builtin name, e.g. "System`EulerPhi" to a Builtin class -system_builtins_dict: Dict[str, Type[Builtin]] = {} - -# builtins_by_module maps a full module name, e.g. "mathics.builtin.evaluation" to a -# list of Builtin classes. -builtins_by_module: Dict[str, List[Type[Builtin]]] = {} - - -def add_builtins(new_builtins: list): - """ - Updates system_builtins_dict to insert 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_dict.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 import_builtins(module_names: List[str], submodule_name=None) -> None: """ @@ -100,48 +55,6 @@ def import_module(module_name: str, import_name: str): 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 - - # 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: redo using importlib since that is probably less fragile. exclude_files = set(("codetables", "base")) module_names = [ @@ -151,8 +64,6 @@ def name_is_builtin_symbol(module, name: str) -> Optional[type]: modules = [] import_builtins(module_names) -_builtins_list = [] - disable_file_module_names = ( [] if ENABLE_FILES_MODULE else ["files_io.files", "files_io.importexport"] ) @@ -192,67 +103,3 @@ def name_is_builtin_symbol(module, name: str) -> Optional[type]: ] # print("XXX3", submodule_names) import_builtins(submodule_names, subdir) - -# FIXME: move this somewhere else... - -# 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): - if not RUN_SANITY_TEST: - return True - - if not hasattr(cls, "summary_text"): - print( - "In ", - module.__name__, - cls.__name__, - " does not have a summary_text.", - ) - return False - return True - - -# End FIXME - - -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) - -mathics_to_sympy: Dict[str, Type[Builtin]] = {} # here we have: name -> sympy object -sympy_to_mathics = {} - -builtins_precedence = {} - -new_builtins = _builtins_list - -add_builtins(new_builtins) - -display_operators_set = set() -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) diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py index 7c00d4dd9..3e2cd88ad 100644 --- a/mathics/builtin/makeboxes.py +++ b/mathics/builtin/makeboxes.py @@ -59,7 +59,7 @@ def int_to_s_exp(expr, n): def parenthesize(precedence, element, element_boxes, when_equal): - from mathics.builtin import builtins_precedence + from mathics.builtin.system_init import builtins_precedence while element.has_form("HoldForm", 1): element = element.elements[0] diff --git a/mathics/builtin/system_init.py b/mathics/builtin/system_init.py index 12dd982cc..213a16fe1 100644 --- a/mathics/builtin/system_init.py +++ b/mathics/builtin/system_init.py @@ -1,12 +1,13 @@ """ -One-time initialization of Mathics built-in functions. - -Eventually - we are not there yet now. Currently this pulls out parts of the Definition class -and mathics.builtin. +One-time initialization of Mathics module loading, and creation of built-in functions. """ +import inspect import os import os.path as osp +from typing import Optional + +from mathics.core.pattern import pattern_objects from mathics.core.atoms import String from mathics.core.evaluation import Evaluation from mathics.core.expression import Expression @@ -15,6 +16,11 @@ from mathics.core.expression import ensure_context from mathics.core.parser import all_operator_names +mathics_to_sympy = {} # here we have: name -> sympy object +sympy_to_mathics = {} + +builtins_precedence = {} + def autoload_files( defs, root_dir_path: str, autoload_dir: str, block_global_definitions: bool = True @@ -39,11 +45,150 @@ def autoload_files( raise ValueError("autoload defined %s." % name) +# builtins_by_module maps a full module name, e.g. "mathics.builtin.evaluation" to a +# list of Builtin classes. +builtins_by_module = {} +_builtins_list = [] + +# system_builtins_dict maps a full builtin name, e.g. "System`EulerPhi" to a Builtin class +system_builtins_dict = {} + + +def add_builtins(new_builtins: list): + """ + Updates system_builtins_dict to insert new_builtins. + """ + from mathics.builtin.base import ( + Operator, + PatternObject, + SympyObject, + mathics_to_python, + ) + + 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_dict.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 create_builtins_by_module(): + from mathics.builtin.base import Builtin + 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) + + +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. + """ + from mathics.builtin.base import Builtin + + 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 + + +# 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): + if not RUN_SANITY_TEST: + return True + + if not hasattr(cls, "summary_text"): + print( + "In ", + module.__name__, + cls.__name__, + " does not have a summary_text.", + ) + return False + return True + + def update_builtin_definitions(builtins: dict, definitions): from mathics.core.definitions import Definition # let MakeBoxes contribute first - builtins["System`MakeBoxes"].contribute(definitions) + makeboxes = builtins.get("System`MakeBoxes") + if makeboxes is not None: + makeboxes.contribute(definitions) for name, item in builtins.items(): if name != "System`MakeBoxes": item.contribute(definitions) @@ -55,3 +200,16 @@ def update_builtin_definitions(builtins: dict, definitions): if not definitions.have_definition(ensure_context(operator)): op = ensure_context(operator) definitions.builtin[op] = Definition(name=op) + + +create_builtins_by_module() +new_builtins = _builtins_list + +add_builtins(new_builtins) +display_operators_set = set() +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) diff --git a/mathics/core/convert/sympy.py b/mathics/core/convert/sympy.py index b10f01333..2ffdfce2b 100644 --- a/mathics/core/convert/sympy.py +++ b/mathics/core/convert/sympy.py @@ -155,7 +155,7 @@ def eval(cls, n): def from_sympy(expr): - from mathics.builtin import sympy_to_mathics + from mathics.builtin.system_init import sympy_to_mathics from mathics.core.atoms import ( Integer, Integer0, diff --git a/mathics/core/definitions.py b/mathics/core/definitions.py index dc2759c59..8576bb25c 100644 --- a/mathics/core/definitions.py +++ b/mathics/core/definitions.py @@ -9,6 +9,11 @@ from collections import defaultdict +# FIXME: should we use deepcopy insteads of copy? +# If so, there are bugs in the code that need to be fixed. +# Do we even need to use copy/deepcopy at all? +from copy import copy + from typing import List, Optional from mathics.core.atoms import String @@ -22,6 +27,7 @@ ) from mathics_scanner.tokeniser import full_names_pattern +from mathics.settings import ROOT_DIR type_compiled_pattern = type(re.compile("a.a")) @@ -49,6 +55,14 @@ def valuesname(name) -> str: return name[7:-6].lower() +# system_definitions contains system-wide defintions used for creating +# builtins. Define system_definitions so we can use it in Definitions +# We declare it here so it can be used in the Definitions class +# However it is initialized to an instance of Definitions below +# after Definitions is defined. +system_definitions = None + + class Definitions: """ The state of one instance of the Mathics interpreter is stored in this object. @@ -81,75 +95,13 @@ def __init__( "Global`", ) - from mathics.core.pymathics import ( - PyMathicsLoadException, - load_pymathics_module, - ) - from mathics.builtin import system_builtins_dict - from mathics.builtin.system_init import ( - autoload_files, - update_builtin_definitions, - ) - - # Importing "mathics.format" populates the Symbol of the - # PrintForms and OutputForms sets. - # - # If "importlib" is used instead of "import", then we get: - # TypeError: boxes_to_text() takes 1 positional argument but - # 2 were given - # Rocky: this smells of something not quite right in terms of - # modularity. - - import mathics.format # noqa - self.printforms = list(PrintForms) self.outputforms = list(OutputForms) self.trace_evaluation = False 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: - builtin_dates = [get_file_time(module.__file__) for module in modules] - builtin_time = max(builtin_dates) - if get_file_time(builtin_filename) > builtin_time: - builtin_file = open(builtin_filename, "rb") - self.builtin = pickle.load(builtin_file) - loaded = True - if not loaded: - update_builtin_definitions(system_builtins_dict, self) - for module in extension_modules: - try: - load_pymathics_module(self, module) - except PyMathicsLoadException: - raise - except ImportError: - raise - - if builtin_filename is not None: - builtin_file = open(builtin_filename, "wb") - pickle.dump(self.builtin, builtin_file, -1) - - autoload_files(self, ROOT_DIR, "autoload") - - # Move any user definitions created by autoloaded files to - # builtins, and clear out the user definitions list. This - # means that any autoloaded definitions become shared - # between users and no longer disappear after a Quit[]. - # - # Autoloads that accidentally define a name in Global` - # could cause confusion, so check for this. - # - for name in self.user: - if name.startswith("Global`"): - raise ValueError("autoload defined %s." % name) - - self.builtin.update(self.user) - self.user = {} - self.clear_cache() + self.builtin = copy(system_definitions.builtin) def clear_cache(self, name=None): # the definitions cache (self.definitions_cache) caches (incomplete and complete) names -> Definition(), @@ -828,3 +780,47 @@ def __repr__(self) -> str: self.name, self.downvalues, self.formatvalues, self.attributes ) return s + + +system_definitions = Definitions(add_builtin=False) + + +def initialize_system_definitions(): + from mathics.builtin.system_init import ( + autoload_files, + update_builtin_definitions, + system_builtins_dict, + ) + + # Importing "mathics.format" populates the Symbol of the + # PrintForms and OutputForms sets. + # + # If "importlib" is used instead of "import", then we get: + # TypeError: boxes_to_text() takes 1 positional argument but + # 2 were given + # Rocky: this smells of something not quite right in terms of + # modularity. + + import mathics.format # noqa + + update_builtin_definitions(system_builtins_dict, system_definitions) + + autoload_files(system_definitions, ROOT_DIR, "autoload") + + # Move any user definitions created by autoloaded files to + # builtins, and clear out the user definitions list. This + # means that any autoloaded definitions become shared + # between users and no longer disappear after a Quit[]. + # + # Autoloads that accidentally define a name in Global` + # could cause confusion, so check for this. + # + for name in system_definitions.user: + if name.startswith("Global`"): + raise ValueError("autoload defined %s." % name) + + system_definitions.builtin.update(system_definitions.user) + system_definitions.user = {} + + +system_definitions = Definitions(add_builtin=False) diff --git a/mathics/core/expression.py b/mathics/core/expression.py index 46adf4321..9749d3193 100644 --- a/mathics/core/expression.py +++ b/mathics/core/expression.py @@ -1446,7 +1446,7 @@ def to_python(self, *args, **kwargs): return self def to_sympy(self, **kwargs): - from mathics.builtin import mathics_to_sympy + from mathics.builtin.system_init import mathics_to_sympy if "convert_all_global_functions" in kwargs: if len(self.elements) > 0 and kwargs["convert_all_global_functions"]: diff --git a/mathics/core/pymathics.py b/mathics/core/pymathics.py index ca1615b8a..43ff8cccb 100644 --- a/mathics/core/pymathics.py +++ b/mathics/core/pymathics.py @@ -23,7 +23,7 @@ def __init__(self, module): # Why do we need this? def eval_clear_pymathics_modules(): global pymathics - from mathics.builtin import builtins_by_module + from mathics.builtin.system_init import builtins_by_module for key in list(builtins_by_module.keys()): if not key.startswith("mathics."): @@ -60,10 +60,10 @@ def load_pymathics_module(definitions, module): Loads Mathics builtin objects and their definitions from an external Python module in the pymathics module namespace. """ - from mathics.builtin import ( + from mathics.builtin.base import Builtin + from mathics.builtin.system_init import ( builtins_by_module, name_is_builtin_symbol, - Builtin, ) if module in sys.modules: diff --git a/mathics/core/rules.py b/mathics/core/rules.py index aa1f66e0b..f7c5aaecf 100644 --- a/mathics/core/rules.py +++ b/mathics/core/rules.py @@ -232,9 +232,9 @@ def __getstate__(self): return odict def __setstate__(self, dict): - from mathics.builtin import _builtins + from mathics.builtin.system_init import system_builtins_dict self.__dict__.update(dict) # update attributes class_name, name = dict["function_"] - self.function = getattr(_builtins[class_name], name) + self.function = getattr(system_builtins_dict[class_name], name) diff --git a/mathics/core/symbols.py b/mathics/core/symbols.py index 8a40d4268..0f8099bbc 100644 --- a/mathics/core/symbols.py +++ b/mathics/core/symbols.py @@ -610,7 +610,7 @@ def to_python(self, *args, python_form: bool = False, **kwargs): return self.name def to_sympy(self, **kwargs): - from mathics.builtin import mathics_to_sympy + from mathics.builtin.system_init import mathics_to_sympy if self.sympy_dummy is not None: return self.sympy_dummy diff --git a/mathics/doc/common_doc.py b/mathics/doc/common_doc.py index 050c25277..4ec77fef0 100644 --- a/mathics/doc/common_doc.py +++ b/mathics/doc/common_doc.py @@ -830,7 +830,7 @@ def __init__(self, want_sorting=False): ( "Reference of Built-in Symbols", builtin.modules, - builtin.builtins_by_module, + builtin.system_init.builtins_by_module, True, ) ]: # nopep8 @@ -1087,7 +1087,7 @@ def __init__(self, module=None): # Load the dictionary of mathics symbols defined in the module self.symbols = {} - from mathics.builtin import name_is_builtin_symbol + from mathics.builtin.system_init import name_is_builtin_symbol from mathics.builtin.base import Builtin print("loading symbols") diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py index 01fa2667c..826d54066 100644 --- a/mathics/docpipeline.py +++ b/mathics/docpipeline.py @@ -21,10 +21,10 @@ import mathics import mathics.settings -from mathics.core.definitions import Definitions +from mathics.core.definitions import Definitions, initialize_system_definitions from mathics.core.evaluation import Evaluation, Output from mathics.core.parser import MathicsSingleLineFeeder -from mathics.builtin import builtins_dict +from mathics.builtin.system_init import builtins_dict from mathics import version_string from mathics import settings @@ -446,6 +446,7 @@ def main(): global definitions global logfile global check_partial_enlapsed_time + initialize_system_definitions() definitions = Definitions(add_builtin=True) parser = ArgumentParser(description="Mathics test suite.", add_help=False) diff --git a/mathics/format/mathml.py b/mathics/format/mathml.py index 12d609d93..23f11b589 100644 --- a/mathics/format/mathml.py +++ b/mathics/format/mathml.py @@ -64,7 +64,7 @@ def encode_mathml(text: str) -> str: def string(self, **options) -> str: - from mathics.builtin import display_operators_set as operators + from mathics.builtin.system_init import display_operators_set as operators text = self.value diff --git a/mathics/main.py b/mathics/main.py index 9e79545a3..7ac446f8e 100755 --- a/mathics/main.py +++ b/mathics/main.py @@ -16,7 +16,7 @@ from mathics.builtin.system_init import autoload_files from mathics.builtin.trace import TraceBuiltins, traced_do_replace from mathics.core.atoms import String -from mathics.core.definitions import Definitions, Symbol +from mathics.core.definitions import Definitions, Symbol, initialize_system_definitions from mathics.core.evaluation import Evaluation, Output from mathics.core.expression import Expression from mathics.core.parser import MathicsFileLineFeeder, MathicsLineFeeder @@ -370,6 +370,7 @@ def dump_tracing_stats(): if args.show_statistics: atexit.register(show_lru_cache_statistics) + initialize_system_definitions() definitions = Definitions(add_builtin=True, extension_modules=extension_modules) definitions.set_line_no(0) diff --git a/test/consistency-and-style/test_duplicate_builtins.py b/test/consistency-and-style/test_duplicate_builtins.py index 56a597c7c..dcbb49bf0 100644 --- a/test/consistency-and-style/test_duplicate_builtins.py +++ b/test/consistency-and-style/test_duplicate_builtins.py @@ -6,8 +6,9 @@ """ import pytest import os -from mathics.builtin import name_is_builtin_symbol, modules +from mathics.builtin import modules from mathics.builtin.base import Builtin +from mathics.builtin.system_init import name_is_builtin_symbol @pytest.mark.skipif( diff --git a/test/consistency-and-style/test_summary_text.py b/test/consistency-and-style/test_summary_text.py index a1bec84de..484564403 100644 --- a/test/consistency-and-style/test_summary_text.py +++ b/test/consistency-and-style/test_summary_text.py @@ -7,8 +7,8 @@ import os.path as osp from mathics.version import __version__ # noqa used in loading to check consistency. -from mathics.builtin import name_is_builtin_symbol from mathics.builtin.base import Builtin +from mathics.builtin.system_init import name_is_builtin_symbol from mathics import __file__ as mathics_initfile_path # Get file system path name for mathics.builtin diff --git a/test/helper.py b/test/helper.py index f0371e82a..7e8a8ae39 100644 --- a/test/helper.py +++ b/test/helper.py @@ -1,8 +1,13 @@ # -*- coding: utf-8 -*- import time -from mathics.session import MathicsSession + from typing import Optional +from mathics.session import MathicsSession +from mathics.core.definitions import initialize_system_definitions + +initialize_system_definitions() + # Set up a Mathics session with definitions. # For consistency set the character encoding ASCII which is # the lowest common denominator available on all systems. From c01508ca95e1c372227fb8ce7fec612da49e8204 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 20 Nov 2022 09:47:59 -0500 Subject: [PATCH 4/9] Move code out of definitions This moves builtin-creation out of mathics.builtin and core.definitions and into a new module. I thing this is the last step before we actually move builtin creation of the Definitions initialization and into some one-time code. --- mathics/builtin/system_init.py | 40 +++++++++++++++++++++++++++++++++ mathics/core/definitions.py | 41 ---------------------------------- mathics/main.py | 4 ++-- 3 files changed, 42 insertions(+), 43 deletions(-) mode change 100755 => 100644 mathics/main.py diff --git a/mathics/builtin/system_init.py b/mathics/builtin/system_init.py index 213a16fe1..e306d1b70 100644 --- a/mathics/builtin/system_init.py +++ b/mathics/builtin/system_init.py @@ -16,6 +16,8 @@ from mathics.core.expression import ensure_context from mathics.core.parser import all_operator_names +from mathics.settings import ROOT_DIR + mathics_to_sympy = {} # here we have: name -> sympy object sympy_to_mathics = {} @@ -213,3 +215,41 @@ def update_builtin_definitions(builtins: dict, definitions): operator = builtin.get_operator_display() if operator is not None: display_operators_set.add(operator) + + +def _initialize_system_definitions(): + from mathics.core.definitions import system_definitions + + # print("Initializing definitions") + # Importing "mathics.format" populates the Symbol of the + # PrintForms and OutputForms sets. + # + # If "importlib" is used instead of "import", then we get: + # TypeError: boxes_to_text() takes 1 positional argument but + # 2 were given + # Rocky: this smells of something not quite right in terms of + # modularity. + + import mathics.format # noqa + + update_builtin_definitions(system_builtins_dict, system_definitions) + + autoload_files(system_definitions, ROOT_DIR, "autoload") + + # Move any user definitions created by autoloaded files to + # builtins, and clear out the user definitions list. This + # means that any autoloaded definitions become shared + # between users and no longer disappear after a Quit[]. + # + # Autoloads that accidentally define a name in Global` + # could cause confusion, so check for this. + # + for name in system_definitions.user: + if name.startswith("Global`"): + raise ValueError("autoload defined %s." % name) + + system_definitions.builtin.update(system_definitions.user) + system_definitions.user = {} + + +_initialize_system_definitions() diff --git a/mathics/core/definitions.py b/mathics/core/definitions.py index 8576bb25c..a3c4c401b 100644 --- a/mathics/core/definitions.py +++ b/mathics/core/definitions.py @@ -783,44 +783,3 @@ def __repr__(self) -> str: system_definitions = Definitions(add_builtin=False) - - -def initialize_system_definitions(): - from mathics.builtin.system_init import ( - autoload_files, - update_builtin_definitions, - system_builtins_dict, - ) - - # Importing "mathics.format" populates the Symbol of the - # PrintForms and OutputForms sets. - # - # If "importlib" is used instead of "import", then we get: - # TypeError: boxes_to_text() takes 1 positional argument but - # 2 were given - # Rocky: this smells of something not quite right in terms of - # modularity. - - import mathics.format # noqa - - update_builtin_definitions(system_builtins_dict, system_definitions) - - autoload_files(system_definitions, ROOT_DIR, "autoload") - - # Move any user definitions created by autoloaded files to - # builtins, and clear out the user definitions list. This - # means that any autoloaded definitions become shared - # between users and no longer disappear after a Quit[]. - # - # Autoloads that accidentally define a name in Global` - # could cause confusion, so check for this. - # - for name in system_definitions.user: - if name.startswith("Global`"): - raise ValueError("autoload defined %s." % name) - - system_definitions.builtin.update(system_definitions.user) - system_definitions.user = {} - - -system_definitions = Definitions(add_builtin=False) diff --git a/mathics/main.py b/mathics/main.py old mode 100755 new mode 100644 index 7ac446f8e..b5b36a24f --- a/mathics/main.py +++ b/mathics/main.py @@ -16,7 +16,8 @@ from mathics.builtin.system_init import autoload_files from mathics.builtin.trace import TraceBuiltins, traced_do_replace from mathics.core.atoms import String -from mathics.core.definitions import Definitions, Symbol, initialize_system_definitions + +from mathics.core.definitions import Definitions, Symbol from mathics.core.evaluation import Evaluation, Output from mathics.core.expression import Expression from mathics.core.parser import MathicsFileLineFeeder, MathicsLineFeeder @@ -370,7 +371,6 @@ def dump_tracing_stats(): if args.show_statistics: atexit.register(show_lru_cache_statistics) - initialize_system_definitions() definitions = Definitions(add_builtin=True, extension_modules=extension_modules) definitions.set_line_no(0) From b5d5c5d49e139b079f69ab46f1188d13521092e0 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 20 Nov 2022 20:44:15 -0500 Subject: [PATCH 5/9] WIP - module load, and builtin create once This isn't working but this is the idea. Another PR will contain some of the independent bugs found in this process --- mathics/builtin/base.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mathics/builtin/base.py b/mathics/builtin/base.py index 3ae3a788e..b1e0dfae9 100644 --- a/mathics/builtin/base.py +++ b/mathics/builtin/base.py @@ -191,7 +191,12 @@ def __new__(cls, *args, **kwargs): # mathics.builtin.inout if kwargs.get("expression", None) is not False: - return to_expression(cls.get_name(), *args) + try: + return to_expression(cls.get_name(), *args) + except: + from trepan.api import debug + + debug() else: instance = super().__new__(cls) if not instance.formats: From 37bffec6de3b7bb8c1df73659d2638edb72bd73c Mon Sep 17 00:00:00 2001 From: mmatera Date: Mon, 21 Nov 2022 15:13:49 -0300 Subject: [PATCH 6/9] patch --- mathics/session.py | 3 ++- test/format/test_asy.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mathics/session.py b/mathics/session.py index 5d4278372..cf7a60e90 100644 --- a/mathics/session.py +++ b/mathics/session.py @@ -14,7 +14,7 @@ from mathics.builtin.system_init import autoload_files from mathics.core.parser import parse, MathicsSingleLineFeeder -from mathics.core.definitions import Definitions +from mathics.core.definitions import Definitions, initialize_system_definitions from mathics.core.evaluation import Evaluation import mathics.settings @@ -72,6 +72,7 @@ def reset(self, add_builtin=True, catch_interrupt=False): """ reset the definitions and the evaluation objects. """ + initialize_system_definitions() self.definitions = Definitions(add_builtin) self.evaluation = Evaluation( definitions=self.definitions, catch_interrupt=catch_interrupt diff --git a/test/format/test_asy.py b/test/format/test_asy.py index 30e43a186..463173d99 100644 --- a/test/format/test_asy.py +++ b/test/format/test_asy.py @@ -8,6 +8,7 @@ from mathics.session import MathicsSession from mathics.builtin.makeboxes import MakeBoxes + session = MathicsSession(add_builtin=True, catch_interrupt=False) evaluation = Evaluation(session.definitions) From f1ccc6d700ab294a85406e2ac98f45fb51014dc4 Mon Sep 17 00:00:00 2001 From: mmatera Date: Mon, 21 Nov 2022 16:23:05 -0300 Subject: [PATCH 7/9] add comment --- mathics/session.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mathics/session.py b/mathics/session.py index cf7a60e90..ddda2cab7 100644 --- a/mathics/session.py +++ b/mathics/session.py @@ -72,6 +72,10 @@ def reset(self, add_builtin=True, catch_interrupt=False): """ reset the definitions and the evaluation objects. """ + # TODO: Due to a fail in the Definitions __init__ method, + # we need to initialize this each time Definitions is + # instantiated. When it gets fixed, the next line + # can be removed. initialize_system_definitions() self.definitions = Definitions(add_builtin) self.evaluation = Evaluation( From 53300f5fbde618656993af8d782a31ccba039c13 Mon Sep 17 00:00:00 2001 From: mmatera Date: Tue, 22 Nov 2022 10:01:16 -0300 Subject: [PATCH 8/9] the true fix: * adding comments * moving _initialize_system_definitions to a better place, and hide it. * fixing contribute in order to make work the pymathics loading mechanism without overwrite builtins --- mathics/builtin/base.py | 30 +++++++++++++++++++++++++-- mathics/docpipeline.py | 4 ++-- mathics/session.py | 7 +------ test/format/test_asy.py | 1 - test/helper.py | 2 -- test/test_custom_boxexpression.py | 34 +++++++++++++++---------------- 6 files changed, 48 insertions(+), 30 deletions(-) diff --git a/mathics/builtin/base.py b/mathics/builtin/base.py index b1e0dfae9..4d8890855 100644 --- a/mathics/builtin/base.py +++ b/mathics/builtin/base.py @@ -3,6 +3,7 @@ import importlib import re + from functools import lru_cache, total_ordering from itertools import chain from typing import Any, Callable, Dict, Iterable, List, Optional, Union, cast @@ -291,7 +292,13 @@ def check_options(options_to_check, evaluation): ) box_rules = [] - # FIXME: Why a special case for System`MakeBoxes? Remove this + + # System`MakeBoxes comes first because all the other symbols contribute to it. + # Then, a definition of this symbol must be available from the begining. + # Probably, this is not a good approach, since it makes that MakeBoxes has + # a very large number of inespecific rules. A better approach would imply at least + # to store the rules as upvalues of the symbols associated to these rules. + # if name != "System`MakeBoxes": new_rules = [] for rule in rules: @@ -389,13 +396,32 @@ def contextify_form_name(f): ) if is_pymodule: definitions.pymathics[name] = definition + try: + makeboxes_def = definitions.pymathics["System`MakeBoxes"] + except KeyError: + builtin_mb_def = definitions.builtin["System`MakeBoxes"] + makeboxes_def = Definition( + "System`MakeBoxes", + builtin=builtin_mb_def.builtin, + attributes=builtin_mb_def.attributes, + is_numeric=builtin_mb_def.is_numeric, + ) + definitions.pymathics["System`MakeBoxes"] = makeboxes_def else: definitions.builtin[name] = definition + makeboxes_def = definitions.builtin["System`MakeBoxes"] - makeboxes_def = definitions.builtin["System`MakeBoxes"] for rule in box_rules: makeboxes_def.add_rule(rule) + # If a pymathics module was loaded, then there are at least two + # definitions for MakeBoxes, the builtin, the pymathics, and the + # cached from combining the former two. Rules are added to one of + # both, which are not going to be in the cached version that + # Definitions.get_definition provides. To make the new rules + # accesible, we need to clear the definitions cache. + definitions.clear_cache("System`MakeBoxes") + @classmethod def get_name(cls, short=False) -> str: if cls.name is None: diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py index 826d54066..29629af22 100644 --- a/mathics/docpipeline.py +++ b/mathics/docpipeline.py @@ -21,7 +21,7 @@ import mathics import mathics.settings -from mathics.core.definitions import Definitions, initialize_system_definitions +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 @@ -446,7 +446,7 @@ def main(): global definitions global logfile global check_partial_enlapsed_time - initialize_system_definitions() + definitions = Definitions(add_builtin=True) parser = ArgumentParser(description="Mathics test suite.", add_help=False) diff --git a/mathics/session.py b/mathics/session.py index ddda2cab7..5d4278372 100644 --- a/mathics/session.py +++ b/mathics/session.py @@ -14,7 +14,7 @@ from mathics.builtin.system_init import autoload_files from mathics.core.parser import parse, MathicsSingleLineFeeder -from mathics.core.definitions import Definitions, initialize_system_definitions +from mathics.core.definitions import Definitions from mathics.core.evaluation import Evaluation import mathics.settings @@ -72,11 +72,6 @@ def reset(self, add_builtin=True, catch_interrupt=False): """ reset the definitions and the evaluation objects. """ - # TODO: Due to a fail in the Definitions __init__ method, - # we need to initialize this each time Definitions is - # instantiated. When it gets fixed, the next line - # can be removed. - initialize_system_definitions() self.definitions = Definitions(add_builtin) self.evaluation = Evaluation( definitions=self.definitions, catch_interrupt=catch_interrupt diff --git a/test/format/test_asy.py b/test/format/test_asy.py index 463173d99..30e43a186 100644 --- a/test/format/test_asy.py +++ b/test/format/test_asy.py @@ -8,7 +8,6 @@ from mathics.session import MathicsSession from mathics.builtin.makeboxes import MakeBoxes - session = MathicsSession(add_builtin=True, catch_interrupt=False) evaluation = Evaluation(session.definitions) diff --git a/test/helper.py b/test/helper.py index 7e8a8ae39..89aa0a2cd 100644 --- a/test/helper.py +++ b/test/helper.py @@ -4,9 +4,7 @@ from typing import Optional from mathics.session import MathicsSession -from mathics.core.definitions import initialize_system_definitions -initialize_system_definitions() # Set up a Mathics session with definitions. # For consistency set the character encoding ASCII which is diff --git a/test/test_custom_boxexpression.py b/test/test_custom_boxexpression.py index 48f4e6c44..6cd8edb0a 100644 --- a/test/test_custom_boxexpression.py +++ b/test/test_custom_boxexpression.py @@ -14,19 +14,19 @@ def __init__(self, evaluation): super().__init__(evaluation=evaluation) self._elements = [1, 2, 3] - def boxes_to_text(self, leaves=None, **options): - if not leaves: - leaves = self.elements + def boxes_to_text(self, elements=None, **options): + if not elements: + elements = self.elements return "CustomBoxExpression<<" + self.elements.__str__() + ">>" - def boxes_to_mathml(self, leaves=None, **options): - if not leaves: - leaves = self.elements + def boxes_to_mathml(self, elements=None, **options): + if not elements: + elements = self.elements return "CustomBoxExpression<<" + self.elements.__str__() + ">>" - def boxes_to_tex(self, leaves=None, **options): - if not leaves: - leaves = self.elements + def boxes_to_tex(self, elements=None, **options): + if not elements: + elements = self.elements return "CustomBoxExpression<<" + int(self.elements) + ">>" @@ -59,25 +59,25 @@ def init(self, *elems, **options): def to_expression(self): return Expression(SymbolCustomGraphicsBox, *self.elements) - def apply_box(self, elems, evaluation, options): - """System`MakeBoxes[System`Graphics[elems_, System`OptionsPattern[System`Graphics]], + def apply_box(self, expr, evaluation, options): + """System`MakeBoxes[System`Graphics[System`expr_, System`OptionsPattern[System`Graphics]], System`StandardForm|System`TraditionalForm|System`OutputForm]""" - instance = CustomGraphicsBox(*(elems.elements), evaluation=evaluation) + instance = CustomGraphicsBox(*(expr.elements), evaluation=evaluation) return instance - def boxes_to_text(self, leaves=None, **options): - if leaves: - self._elements = leaves + def boxes_to_text(self, elements=None, **options): + if elements: + self._elements = elements return ( "--custom graphics--: I should plot " + self.elements.__str__() + " items" ) - def boxes_to_tex(self, leaves=None, **options): + def boxes_to_tex(self, elements=None, **options): return ( "--custom graphics--: I should plot " + self.elements.__str__() + " items" ) - def boxes_to_mathml(self, leaves=None, **options): + def boxes_to_mathml(self, elements=None, **options): return ( "--custom graphics--: I should plot " + self.elements.__str__() + " items" ) From c91482333034609847bc79cc5641ec173b79ffbc Mon Sep 17 00:00:00 2001 From: mmatera Date: Sun, 27 Nov 2022 00:19:52 -0300 Subject: [PATCH 9/9] merge --- mathics/docpipeline.py | 2 +- mathics/main.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mathics/docpipeline.py b/mathics/docpipeline.py index 7962408d8..29629af22 100644 --- a/mathics/docpipeline.py +++ b/mathics/docpipeline.py @@ -21,7 +21,7 @@ import mathics import mathics.settings -from mathics.core.definitions import Definitions, initialize_system_definitions +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 diff --git a/mathics/main.py b/mathics/main.py index c1f983214..b5b36a24f 100644 --- a/mathics/main.py +++ b/mathics/main.py @@ -371,7 +371,6 @@ def dump_tracing_stats(): if args.show_statistics: atexit.register(show_lru_cache_statistics) - initialize_system_definitions() definitions = Definitions(add_builtin=True, extension_modules=extension_modules) definitions.set_line_no(0)