Skip to content

Commit fb77260

Browse files
authored
Merge pull request #899 from Mathics3/module_load_refactor-part2
A second pass at redoing load_builtin.py
2 parents 3810242 + 86bfa5c commit fb77260

File tree

3 files changed

+88
-56
lines changed

3 files changed

+88
-56
lines changed

mathics/core/load_builtin.py

Lines changed: 86 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
import pkgutil
1414
from glob import glob
1515
from types import ModuleType
16-
from typing import List, Optional
16+
from typing import Dict, List, Optional, Set
1717

18+
from mathics.core.convert.sympy import mathics_to_sympy, sympy_to_mathics
1819
from mathics.core.pattern import pattern_objects
1920
from mathics.core.symbols import Symbol
2021
from mathics.eval.makeboxes import builtins_precedence
@@ -27,11 +28,55 @@
2728
mathics3_builtins_modules: List[ModuleType] = []
2829

2930
_builtins = {}
30-
builtins_by_module = {}
31-
display_operators_set = set()
3231

32+
# builtins_by_module gives a way of mapping a Python module name
33+
# e.g. 'mathics.builtin.arithmetic' to the list of Builtin class instances
34+
# that appear inside that module, e.g. for key 'mathics.builtin.arithmetic' we
35+
# have:
36+
# [<mathics.builtin.arithmetic.Arg object>, <mathics.builtin.arithmetic.Assuming object, ...]
37+
#
38+
builtins_by_module: Dict[str, list] = {}
3339

34-
# The fact that are importing inside here, suggests add_builtins
40+
# Set operators strings, unary, binary, or ternary.
41+
# For example "!, "!!", ^, "+", "-", ">=", "===", "<<", etc.
42+
display_operators_set: Set[str] = set()
43+
44+
45+
def add_builtins_from_builtin_module(module: ModuleType, builtins_list: list):
46+
"""
47+
Process a modules which contains Builtin classes so that the
48+
class is imported in the Python sense but also that we
49+
have information added to module variable ``builtins_by_module``.
50+
51+
"""
52+
from mathics.core.builtin import Builtin
53+
54+
builtins_by_module[module.__name__] = []
55+
module_vars = dir(module)
56+
57+
for name in module_vars:
58+
builtin_class = name_is_builtin_symbol(module, name)
59+
if builtin_class is not None:
60+
instance = builtin_class(expression=False)
61+
62+
if isinstance(instance, Builtin):
63+
# This set the default context for symbols in mathics.builtins
64+
if not type(instance).context:
65+
type(instance).context = "System`"
66+
builtins_list.append((instance.get_name(), instance))
67+
builtins_by_module[module.__name__].append(instance)
68+
update_display_operators_set(instance)
69+
70+
71+
def add_builtins_from_builtin_modules(modules: List[ModuleType]):
72+
builtins_list = []
73+
for module in modules:
74+
add_builtins_from_builtin_module(module, builtins_list)
75+
add_builtins(builtins_list)
76+
return builtins_by_module
77+
78+
79+
# The fact that we are importing inside here, suggests add_builtins
3580
# should get moved elsewhere.
3681
def add_builtins(new_builtins):
3782
from mathics.core.builtin import (
@@ -40,7 +85,6 @@ def add_builtins(new_builtins):
4085
SympyObject,
4186
mathics_to_python,
4287
)
43-
from mathics.core.convert.sympy import mathics_to_sympy, sympy_to_mathics
4488

4589
for _, builtin in new_builtins:
4690
name = builtin.get_name()
@@ -54,37 +98,13 @@ def add_builtins(new_builtins):
5498
# print("XXX1", sympy_name)
5599
sympy_to_mathics[sympy_name] = builtin
56100
if isinstance(builtin, Operator):
101+
assert builtin.precedence is not None
57102
builtins_precedence[Symbol(name)] = builtin.precedence
58103
if isinstance(builtin, PatternObject):
59104
pattern_objects[name] = builtin.__class__
60105
_builtins.update(dict(new_builtins))
61106

62107

63-
def add_builtins_from_builtin_modules(modules: List[ModuleType]):
64-
# This can be put at the top after mathics.builtin.__init__
65-
# cleanup is done.
66-
from mathics.core.builtin import Builtin
67-
68-
builtins_list = []
69-
for module in modules:
70-
builtins_by_module[module.__name__] = []
71-
module_vars = dir(module)
72-
73-
for name in module_vars:
74-
builtin_class = name_is_builtin_symbol(module, name)
75-
if builtin_class is not None:
76-
instance = builtin_class(expression=False)
77-
78-
if isinstance(instance, Builtin):
79-
# This set the default context for symbols in mathics.builtins
80-
if not type(instance).context:
81-
type(instance).context = "System`"
82-
builtins_list.append((instance.get_name(), instance))
83-
builtins_by_module[module.__name__].append(instance)
84-
add_builtins(builtins_list)
85-
return builtins_by_module
86-
87-
88108
def builtins_dict(builtins_by_module):
89109
return {
90110
builtin.get_name(): builtin
@@ -143,13 +163,32 @@ def import_and_load_builtins():
143163
# server, we disallow local file access.
144164
disable_file_module_names = set() if ENABLE_FILES_MODULE else {"files_io"}
145165

146-
subdirectories = next(os.walk(builtin_path))[1]
166+
subdirectory_list = next(os.walk(builtin_path))[1]
167+
subdirectories = set(subdirectory_list) - set("__pycache__")
147168
import_builtin_subdirectories(
148169
subdirectories, disable_file_module_names, mathics3_builtins_modules
149170
)
150171

151172
add_builtins_from_builtin_modules(mathics3_builtins_modules)
152-
initialize_display_operators_set()
173+
174+
175+
def import_builtin_module(import_name: str, modules: List[ModuleType]):
176+
"""
177+
Imports ``the list of Mathics3 Built-in modules so that inside
178+
Mathics3 Builtin Functions, like Plus[], List[] are defined.
179+
180+
List ``module_names`` is updated.
181+
"""
182+
try:
183+
module = importlib.import_module(import_name)
184+
except Exception as e:
185+
print(e)
186+
print(f" Not able to load {import_name}. Check your installation.")
187+
print(f" mathics.builtin loads from {__file__[:-11]}")
188+
return None
189+
190+
if module:
191+
modules.append(module)
153192

154193

155194
# TODO: When we drop Python 3.7,
@@ -162,34 +201,24 @@ def import_builtins(
162201
"""
163202
Imports the list of Mathics3 Built-in modules so that inside
164203
Mathics3 Builtin Functions, like Plus[], List[] are defined.
165-
"""
166204
167-
def import_module(module_name: str, import_name: str):
168-
try:
169-
module = importlib.import_module(import_name)
170-
except Exception as e:
171-
print(e)
172-
print(f" Not able to load {module_name}. Check your installation.")
173-
print(f" mathics.builtin loads from {__file__[:-11]}")
174-
return None
175-
176-
if module:
177-
modules.append(module)
205+
List ``module_names`` is updated.
206+
"""
178207

179208
if submodule_name:
180-
import_module(submodule_name, f"mathics.builtin.{submodule_name}")
209+
import_builtin_module(f"mathics.builtin.{submodule_name}", modules)
181210

182211
for module_name in module_names:
183212
import_name = (
184213
f"mathics.builtin.{submodule_name}.{module_name}"
185214
if submodule_name
186215
else f"mathics.builtin.{module_name}"
187216
)
188-
import_module(module_name, import_name)
217+
import_builtin_module(import_name, modules)
189218

190219

191220
def import_builtin_subdirectories(
192-
subdirectories: List[str], disable_file_module_names: set, modules
221+
subdirectories: Set[str], disable_file_module_names: set, modules
193222
):
194223
"""
195224
Runs import_builtisn on the each subdirectory in ``subdirectories`` that inside
@@ -209,15 +238,6 @@ def import_builtin_subdirectories(
209238
import_builtins(submodule_names, modules, subdir)
210239

211240

212-
def initialize_display_operators_set():
213-
for _, builtins in builtins_by_module.items():
214-
for builtin in builtins:
215-
# name = builtin.get_name()
216-
operator = builtin.get_operator_display()
217-
if operator is not None:
218-
display_operators_set.add(operator)
219-
220-
221241
def name_is_builtin_symbol(module: ModuleType, name: str) -> Optional[type]:
222242
"""
223243
Checks if ``name`` should be added to definitions, and return
@@ -277,3 +297,13 @@ def name_is_builtin_symbol(module: ModuleType, name: str) -> Optional[type]:
277297
if module_object in getattr(module, "DOES_NOT_ADD_BUILTIN_DEFINITION", []):
278298
return None
279299
return module_object
300+
301+
302+
def update_display_operators_set(builtin_instance):
303+
"""
304+
If builtin_instance is an operator of some kind, add that
305+
to the set of opererator strings ``display_operators_set``.
306+
"""
307+
operator = builtin_instance.get_operator_display()
308+
if operator is not None:
309+
display_operators_set.add(operator)

mathics/data/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/doc_latex_data.pcl
2+
/doctest_latex_data.pcl
23
/op-tables.json

mathics/doc/latex/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/core-version.tex
22
/doc_latex_data.pcl
3+
/documentation.log
34
/documentation.tex
45
/documentation.tex-before-sed
56
/images/

0 commit comments

Comments
 (0)