Skip to content

Commit

Permalink
builtin.system_init -> core.system_init
Browse files Browse the repository at this point in the history
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

Merge mess
  • Loading branch information
rocky committed Dec 7, 2022
1 parent 3251989 commit e1e0c44
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 101 deletions.
2 changes: 1 addition & 1 deletion examples/symbolic_logic/gries_schneider/test_gs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
80 changes: 5 additions & 75 deletions mathics/builtin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@
among other things.
"""

import glob
import importlib
import inspect
import os.path as osp
import pkgutil
import re
from typing import List, Optional
from typing import List

from mathics.builtin.base import (
Builtin,
Expand All @@ -36,15 +33,10 @@
mathics_to_python,
)
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

# Get 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.
__py_files__ = [
osp.basename(f[0:-3])
for f in glob.glob(osp.join(osp.dirname(__file__), "[a-z]*.py"))
]

__py_files__ = get_builtin_pyfiles()

mathics_to_sympy = {} # here we have: name -> sympy object
sympy_to_mathics = {}
Expand Down Expand Up @@ -74,26 +66,6 @@ def add_builtins(new_builtins):
system_builtins.update(dict(new_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 import_builtins(module_names: List[str], submodule_name=None) -> None:
"""
Imports the list of Mathics Built-in modules so that inside
Expand Down Expand Up @@ -125,48 +97,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 = {"codetables", "base"}
module_names = [
Expand Down Expand Up @@ -231,8 +161,8 @@ def name_is_builtin_symbol(module, name: str) -> Optional[type]:
# This set the default context for symbols in mathics.builtins
if not type(instance).context:
type(instance).context = "System`"

builtins_list.append((instance.get_name(), instance))
builtins_by_module[module.__name__].append(instance)

new_builtins = builtins_list
add_builtins(new_builtins)
add_builtins(builtins_list)
3 changes: 2 additions & 1 deletion mathics/core/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -130,7 +131,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
Expand Down
3 changes: 1 addition & 2 deletions mathics/core/pymathics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import sys


from mathics.builtin.system_init import builtins_by_module
from mathics.core.evaluation import Evaluation
from mathics.core.system_init import builtins_by_module, name_is_builtin_symbol

# This dict probably does not belong here.
pymathics = {}
Expand Down Expand Up @@ -61,7 +61,6 @@ def load_pymathics_module(definitions, module):
"""
from mathics.builtin import (
builtins_by_module,
name_is_builtin_symbol,
Builtin,
)

Expand Down
105 changes: 89 additions & 16 deletions mathics/builtin/system_init.py → mathics/core/system_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@
"""

import glob
import inspect
import os.path as osp

from mathics.builtin.base import (
Builtin,
Operator,
PatternObject,
SympyObject,
mathics_to_python,
)
from typing import Optional

from mathics.core.pattern import pattern_objects

Expand All @@ -37,6 +31,13 @@


def add_builtins(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"):
Expand All @@ -63,8 +64,29 @@ def builtins_dict():
}


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, name_is_builtin_symbol, sanity_check
from mathics.builtin import modules
from mathics.builtin.base import Builtin

for module in modules:
builtins_by_module[module.__name__] = []
Expand All @@ -79,12 +101,22 @@ def create_builtins_by_module():
# 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__), "..", "builtin", "[a-z]*.py")
)
)


display_operators_set = set()
Expand All @@ -100,12 +132,53 @@ def initialize_system():
Not much here but more may be added.
"""
create_builtins_by_module()
from mathics.builtin import __py_files__ as old_py_files

assert __py_files__ == old_py_files
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.
"""
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
5 changes: 4 additions & 1 deletion mathics/doc/common_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion mathics/docpipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion mathics/format/mathml.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion mathics/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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


Expand Down
2 changes: 1 addition & 1 deletion mathics/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
Loading

0 comments on commit e1e0c44

Please sign in to comment.