Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move builtin loading code entirely out of __init__ #879

Merged
merged 2 commits into from
Jul 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion admin-tools/build_and_check_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

import sys

from mathics.builtin import Builtin, modules, name_is_builtin_symbol
from mathics.builtin.base import Builtin
from mathics.core.load_builtin import (
import_and_load_builtins,
modules,
name_is_builtin_symbol,
)

import_and_load_builtins()


def generate_available_builtins_names():
Expand Down
2 changes: 2 additions & 0 deletions examples/symbolic_logic/gries_schneider/test_gs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

from mathics.core.definitions import Definitions
from mathics.core.evaluation import Evaluation
from mathics.core.load_builtin import import_and_load_builtins
from mathics.core.parser import MathicsSingleLineFeeder, parse

import_and_load_builtins()
definitions = Definitions(add_builtin=True)

for i in range(0, 4):
Expand Down
35 changes: 0 additions & 35 deletions mathics/builtin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,3 @@
builtin class such as the Builtin's Attributes, its Information text,
among other things.
"""

import os
import os.path as osp

from mathics.core.load_builtin import (
add_builtins_from_builtin_modules,
get_module_names,
import_builtin_subdirectories,
import_builtins,
initialize_display_operators_set,
)
from mathics.settings import ENABLE_FILES_MODULE

# Get import modules in this directory of Python modules that contain
# Mathics3 Builtin class definitions.

builtin_path = osp.dirname(__file__)
exclude_files = {"codetables", "base"}
module_names = get_module_names(builtin_path, exclude_files)
modules = []
import_builtins(module_names, modules)

# Get import modules in subdirectories of this directory of Python
# modules that contain Mathics3 Builtin class definitions.

# The files_io module handles local file access, reading and writing..
# In some sandboxed settings, such as running Mathics from as a remote
# server, we disallow local file access.
disable_file_module_names = set() if ENABLE_FILES_MODULE else {"files_io"}

subdirectories = next(os.walk(builtin_path))[1]
import_builtin_subdirectories(subdirectories, disable_file_module_names, modules)

add_builtins_from_builtin_modules(modules)
initialize_display_operators_set()
5 changes: 2 additions & 3 deletions mathics/core/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
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.load_builtin import definition_contribute, modules
from mathics.core.symbols import Atom, Symbol, strip_context
from mathics.core.systemsymbols import SymbolGet
from mathics.settings import ROOT_DIR

type_compiled_pattern = type(re.compile("a.a"))

Expand Down Expand Up @@ -138,8 +139,6 @@ def __init__(
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:
Expand Down
36 changes: 36 additions & 0 deletions mathics/core/load_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import importlib
import inspect
import os
import os.path as osp
import pkgutil
from glob import glob
Expand All @@ -16,6 +17,11 @@
from mathics.core.pattern import pattern_objects
from mathics.core.symbols import Symbol
from mathics.eval.makeboxes import builtins_precedence
from mathics.settings import ENABLE_FILES_MODULE

# List of Mathics3 Builtin modules.
# This is initialized via below import_builtins modules
modules = []
Copy link
Member Author

@rocky rocky Jul 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"modules" is a too vague a name. Probably mathics3_builtin_modules is better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree


_builtins = {}
builtins_by_module = {}
Expand Down Expand Up @@ -110,6 +116,36 @@ def get_module_names(builtin_path: str, exclude_files: set) -> list:
return [f for f in py_files if f not in exclude_files]


def import_and_load_builtins():
"""
Imports Builtin modules in mathics.builtin and add rules, and definitions from that.
"""
builtin_path = osp.join(
osp.dirname(
__file__,
),
"..",
"builtin",
)
exclude_files = {"codetables", "base"}
module_names = get_module_names(builtin_path, exclude_files)
import_builtins(module_names, modules)

# Get import modules in subdirectories of this directory of Python
# modules that contain Mathics3 Builtin class definitions.

# The files_io module handles local file access, reading and writing..
# In some sandboxed settings, such as running Mathics from as a remote
# server, we disallow local file access.
disable_file_module_names = set() if ENABLE_FILES_MODULE else {"files_io"}

subdirectories = next(os.walk(builtin_path))[1]
import_builtin_subdirectories(subdirectories, disable_file_module_names, modules)

add_builtins_from_builtin_modules(modules)
initialize_display_operators_set()


# TODO: When we drop Python 3.7,
# module_names can be a List[Literal]
def import_builtins(
Expand Down
9 changes: 6 additions & 3 deletions mathics/doc/common_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@
from types import ModuleType
from typing import Callable

from mathics import builtin, settings
from mathics import settings
from mathics.builtin.base import check_requires_list
from mathics.core.evaluation import Message, Print
from mathics.core.load_builtin import builtins_by_module as global_builtins_by_module
from mathics.core.load_builtin import (
builtins_by_module as global_builtins_by_module,
modules as mathics3_builtin_modules,
)
from mathics.core.util import IS_PYPY
from mathics.doc.utils import slugify
from mathics.eval.pymathics import pymathics_builtins_by_module, pymathics_modules
Expand Down Expand Up @@ -635,7 +638,7 @@ def gather_doctest_data(self):
for title, modules, builtins_by_module, start in [
(
"Reference of Built-in Symbols",
builtin.modules,
mathics3_builtin_modules,
global_builtins_by_module,
True,
)
Expand Down
9 changes: 7 additions & 2 deletions mathics/docpipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
from mathics import settings, version_string
from mathics.core.definitions import Definitions
from mathics.core.evaluation import Evaluation, Output
from mathics.core.load_builtin import builtins_by_module, builtins_dict
from mathics.core.load_builtin import (
builtins_by_module,
builtins_dict,
import_and_load_builtins,
)
from mathics.core.parser import MathicsSingleLineFeeder
from mathics.doc.common_doc import MathicsMainDocumentation
from mathics.eval.pymathics import PyMathicsLoadException, eval_LoadModule
Expand Down Expand Up @@ -177,7 +181,6 @@ def test_tests(
max_tests=MAX_TESTS,
excludes=[],
):

# For consistency set the character encoding ASCII which is
# the lowest common denominator available on all systems.
mathics.settings.SYSTEM_CHARACTER_ENCODING = "ASCII"
Expand Down Expand Up @@ -487,6 +490,8 @@ def main():
global definitions
global logfile
global check_partial_elapsed_time

import_and_load_builtins()
definitions = Definitions(add_builtin=True)

parser = ArgumentParser(description="Mathics test suite.", add_help=False)
Expand Down
3 changes: 3 additions & 0 deletions mathics/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
from mathics.core.definitions import Definitions, Symbol, autoload_files
from mathics.core.evaluation import Evaluation, Output
from mathics.core.expression import Expression
from mathics.core.load_builtin import import_and_load_builtins
from mathics.core.parser import MathicsFileLineFeeder, MathicsLineFeeder
from mathics.core.read import channel_to_stream
from mathics.core.rules import BuiltinRule
from mathics.core.streams import stream_manager
from mathics.core.symbols import SymbolNull, strip_context
from mathics.timing import show_lru_cache_statistics

import_and_load_builtins()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that this section is isolated we could and should be able to time how long running this subroutine takes.



def get_srcdir():
filename = osp.normcase(osp.dirname(osp.abspath(__file__)))
Expand Down
2 changes: 1 addition & 1 deletion mathics/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# well as importing into Python. That's why there is no
# space around "=" below.
# fmt: off
__version__="6.0.2dev0" # noqa
__version__="6.1.0dev0" # noqa
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably should be 7.0.0. Even before this change there were a number of API breaking changes. You'll see them in the recent Mathics3 Modules (natlang, and graph). And we'll have to change these more for this as well.

12 changes: 7 additions & 5 deletions test/consistency-and-style/test_duplicate_builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@

import pytest

from mathics.builtin import modules
from mathics.builtin.base import Builtin
from mathics.core.load_builtin import name_is_builtin_symbol
from mathics.core.load_builtin import modules, name_is_builtin_symbol


@pytest.mark.skipif(
Expand All @@ -33,15 +32,18 @@ def test_check_duplicated():
"""
assert (
builtins_by_name.get(name, None) is None
), f"{name} defined in {module} already defined in {builtins_by_name[name]}."
), f"{name} defined in {module} already defined in "
f{builtins_by_name[name]}."
"""
# if builtins_by_name.get(name, None) is not None:
# print(
# f"\n{name} defined in {module} already defined in {builtins_by_name[name]}."
# (f"\n{name} defined in {module} already defined in
# f{builtins_by_name[name]}.")
# )
# msg = (
# msg
# + f"\n{name} defined in {module} already defined in {builtins_by_name[name]}."
# + (f"\n{name} defined in {module} already defined in "
# {builtins_by_name[name]}.")
# )
builtins_by_name[name] = module
assert msg == "", msg
3 changes: 3 additions & 0 deletions test/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
import time
from typing import Optional

from mathics.core.load_builtin import import_and_load_builtins
from mathics.session import MathicsSession

import_and_load_builtins()

# Set up a Mathics session with definitions.
# For consistency set the character encoding ASCII which is
# the lowest common denominator available on all systems.
Expand Down