4
4
located in static files and docstrings from
5
5
Mathics3 Builtin Modules. Builtin Modules are written in Python and
6
6
reside either in the Mathics3 core (mathics.builtin) or are packaged outside,
7
- e.g. pymathics.natlang.
7
+ in Mathics3 Modules e.g. pymathics.natlang.
8
8
9
9
This data is stored in a way that facilitates:
10
10
* organizing information to produce a LaTeX file
35
35
import re
36
36
from os import environ , getenv , listdir
37
37
from types import ModuleType
38
- from typing import Callable , Iterator , List , Optional , Tuple
38
+ from typing import Callable , List , Optional , Tuple
39
39
40
40
from mathics import settings
41
41
from mathics .core .builtin import check_requires_list
@@ -694,13 +694,9 @@ def get_subsection(self, part_slug, chapter_slug, section_slug, subsection_slug)
694
694
695
695
return None
696
696
697
- def get_tests (self , want_sorting = False ):
697
+ def get_tests (self ):
698
698
for part in self .parts :
699
- if want_sorting :
700
- chapter_collection_fn = lambda x : sorted_chapters (x )
701
- else :
702
- chapter_collection_fn = lambda x : x
703
- for chapter in chapter_collection_fn (part .chapters ):
699
+ for chapter in sorted_chapters (part .chapters ):
704
700
tests = chapter .doc .get_tests ()
705
701
if tests :
706
702
yield Tests (part .title , chapter .title , "" , tests )
@@ -1045,10 +1041,97 @@ def add_subsection(
1045
1041
)
1046
1042
section .subsections .append (subsection )
1047
1043
1044
+ def doc_chapter (self , module , part , builtins_by_module ) -> Optional [DocChapter ]:
1045
+ """
1046
+ Build documentation structure for a "Chapter" - reference section which
1047
+ might be a Mathics Module.
1048
+ """
1049
+ modules_seen = set ([])
1050
+
1051
+ title , text = get_module_doc (module )
1052
+ chapter = self .chapter_class (part , title , self .doc_class (text , title , None ))
1053
+ builtins = builtins_by_module .get (module .__name__ )
1054
+ if module .__file__ .endswith ("__init__.py" ):
1055
+ # We have a Guide Section.
1056
+
1057
+ # This is used to check if a symbol is not duplicated inside
1058
+ # a guide.
1059
+ submodule_names_seen = set ([])
1060
+ name = get_doc_name_from_module (module )
1061
+ guide_section = self .add_section (
1062
+ chapter , name , module , operator = None , is_guide = True
1063
+ )
1064
+ submodules = [
1065
+ value
1066
+ for value in module .__dict__ .values ()
1067
+ if isinstance (value , ModuleType )
1068
+ ]
1069
+
1070
+ sorted_submodule = lambda x : sorted (
1071
+ submodules ,
1072
+ key = lambda submodule : submodule .sort_order
1073
+ if hasattr (submodule , "sort_order" )
1074
+ else submodule .__name__ ,
1075
+ )
1076
+
1077
+ # Add sections in the guide section...
1078
+ for submodule in sorted_submodule (submodules ):
1079
+ if skip_module_doc (submodule , modules_seen ):
1080
+ continue
1081
+ elif IS_PYPY and submodule .__name__ == "builtins" :
1082
+ # PyPy seems to add this module on its own,
1083
+ # but it is not something that can be importable
1084
+ continue
1085
+
1086
+ submodule_name = get_doc_name_from_module (submodule )
1087
+ if submodule_name in submodule_names_seen :
1088
+ continue
1089
+ section = self .add_section (
1090
+ chapter ,
1091
+ submodule_name ,
1092
+ submodule ,
1093
+ operator = None ,
1094
+ is_guide = False ,
1095
+ in_guide = True ,
1096
+ )
1097
+ modules_seen .add (submodule )
1098
+ submodule_names_seen .add (submodule_name )
1099
+ guide_section .subsections .append (section )
1100
+
1101
+ builtins = builtins_by_module .get (submodule .__name__ , [])
1102
+ subsections = [builtin for builtin in builtins ]
1103
+ for instance in subsections :
1104
+ if hasattr (instance , "no_doc" ) and instance .no_doc :
1105
+ continue
1106
+
1107
+ name = instance .get_name (short = True )
1108
+ if name in submodule_names_seen :
1109
+ continue
1110
+
1111
+ submodule_names_seen .add (name )
1112
+ modules_seen .add (instance )
1113
+
1114
+ self .add_subsection (
1115
+ chapter ,
1116
+ section ,
1117
+ name ,
1118
+ instance ,
1119
+ instance .get_operator (),
1120
+ in_guide = True ,
1121
+ )
1122
+ else :
1123
+ if not builtins :
1124
+ return None
1125
+ sections = [
1126
+ builtin for builtin in builtins if not skip_doc (builtin .__class__ )
1127
+ ]
1128
+ self .doc_sections (sections , modules_seen , chapter )
1129
+ return chapter
1130
+
1048
1131
def doc_part (self , title , modules , builtins_by_module , start ):
1049
1132
"""
1050
- Produce documentation for a "Part" - reference section or
1051
- possibly Pymathics modules
1133
+ Build documentation structure for a "Part" - Reference
1134
+ section or collection of Mathics3 Modules.
1052
1135
"""
1053
1136
1054
1137
builtin_part = self .part_class (self , title , is_reference = start )
@@ -1060,20 +1143,6 @@ def doc_part(self, title, modules, builtins_by_module, start):
1060
1143
# packages inside ``mathics.builtin``.
1061
1144
modules_seen = set ([])
1062
1145
1063
- want_sorting = True
1064
- if want_sorting :
1065
- module_collection_fn = lambda x : sorted (
1066
- modules ,
1067
- key = lambda module : module .sort_order
1068
- if hasattr (module , "sort_order" )
1069
- else module .__name__ ,
1070
- )
1071
- else :
1072
- module_collection_fn = lambda x : x
1073
-
1074
- # For some weird reason, it seems that this produces an
1075
- # overflow error in test.builitin.directories.
1076
- '''
1077
1146
def filter_toplevel_modules (module_list ):
1078
1147
"""
1079
1148
Keep just the modules at the top level.
@@ -1087,105 +1156,28 @@ def filter_toplevel_modules(module_list):
1087
1156
)
1088
1157
top_level = modules_and_levels [0 ][0 ]
1089
1158
return (entry [1 ] for entry in modules_and_levels if entry [0 ] == top_level )
1090
- '''
1091
- # This ensures that the chapters are built
1092
- # from the top-level modules. Without this,
1093
- # if this happens is just by chance, or by
1094
- # an obscure combination between the sorting
1095
- # of the modules and the way in which visited
1096
- # modules are skipped.
1097
- #
1098
- # However, if I activate this, some tests are lost.
1159
+
1160
+ # The loop to load chapters must be run over the top-level modules. Otherwise,
1161
+ # modules like ``mathics.builtin.functional.apply_fns_to_lists`` are loaded
1162
+ # as chapters and sections of a GuideSection, producing duplicated tests.
1099
1163
#
1100
- # modules = filter_toplevel_modules(modules)
1101
- for module in module_collection_fn (modules ):
1164
+ # Also, this provides a more deterministic way to walk the module hierarchy,
1165
+ # which can be decomposed in the way proposed in #984.
1166
+
1167
+ modules = filter_toplevel_modules (modules )
1168
+ for module in sorted (
1169
+ modules ,
1170
+ key = lambda module : module .sort_order
1171
+ if hasattr (module , "sort_order" )
1172
+ else module .__name__ ,
1173
+ ):
1102
1174
if skip_module_doc (module , modules_seen ):
1103
1175
continue
1104
- title , text = get_module_doc (module )
1105
- chapter = self .chapter_class (
1106
- builtin_part , title , self .doc_class (text , title , None )
1107
- )
1108
- builtins = builtins_by_module .get (module .__name__ )
1109
- if module .__file__ .endswith ("__init__.py" ):
1110
- # We have a Guide Section.
1111
-
1112
- # This is used to check if a symbol is not duplicated inside
1113
- # a guide.
1114
- submodule_names_seen = set ([])
1115
- name = get_doc_name_from_module (module )
1116
- guide_section = self .add_section (
1117
- chapter , name , module , operator = None , is_guide = True
1118
- )
1119
- submodules = [
1120
- value
1121
- for value in module .__dict__ .values ()
1122
- if isinstance (value , ModuleType )
1123
- ]
1124
-
1125
- sorted_submodule = lambda x : sorted (
1126
- submodules ,
1127
- key = lambda submodule : submodule .sort_order
1128
- if hasattr (submodule , "sort_order" )
1129
- else submodule .__name__ ,
1130
- )
1131
-
1132
- # Add sections in the guide section...
1133
- for submodule in sorted_submodule (submodules ):
1134
- if skip_module_doc (submodule , modules_seen ):
1135
- continue
1136
- elif IS_PYPY and submodule .__name__ == "builtins" :
1137
- # PyPy seems to add this module on its own,
1138
- # but it is not something that can be importable
1139
- continue
1140
-
1141
- submodule_name = get_doc_name_from_module (submodule )
1142
- # This has the side effect that Symbols with the same
1143
- # short name but in different contexts be skipped.
1144
- # This happens with ``PlaintextImport`` that appears in
1145
- # the HTML and XML contexts.
1146
- if submodule_name in submodule_names_seen :
1147
- continue
1148
- section = self .add_section (
1149
- chapter ,
1150
- submodule_name ,
1151
- submodule ,
1152
- operator = None ,
1153
- is_guide = False ,
1154
- in_guide = True ,
1155
- )
1156
- modules_seen .add (submodule )
1157
- submodule_names_seen .add (submodule_name )
1158
- guide_section .subsections .append (section )
1159
-
1160
- builtins = builtins_by_module .get (submodule .__name__ , [])
1161
- subsections = [builtin for builtin in builtins ]
1162
- for instance in subsections :
1163
- if hasattr (instance , "no_doc" ) and instance .no_doc :
1164
- continue
1165
-
1166
- name = instance .get_name (short = True )
1167
- if name in submodule_names_seen :
1168
- continue
1169
-
1170
- submodule_names_seen .add (name )
1171
- modules_seen .add (instance )
1172
-
1173
- self .add_subsection (
1174
- chapter ,
1175
- section ,
1176
- name ,
1177
- instance ,
1178
- instance .get_operator (),
1179
- in_guide = True ,
1180
- )
1181
- else :
1182
- if not builtins :
1183
- continue
1184
- sections = [
1185
- builtin for builtin in builtins if not skip_doc (builtin .__class__ )
1186
- ]
1187
- self .doc_sections (sections , modules_seen , chapter )
1176
+ chapter = self .doc_chapter (module , builtin_part , builtins_by_module )
1177
+ if chapter is None :
1178
+ continue
1188
1179
builtin_part .chapters .append (chapter )
1180
+
1189
1181
self .parts .append (builtin_part )
1190
1182
1191
1183
def doc_sections (self , sections , modules_seen , chapter ):
0 commit comments