mapFolding 0.10.0__tar.gz → 0.11.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mapfolding-0.10.0 → mapfolding-0.11.1}/PKG-INFO +2 -1
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/__init__.py +12 -27
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +9 -11
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/__init__.py +20 -24
- mapfolding-0.11.1/mapFolding/someAssemblyRequired/_toolIfThis.py +59 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/_toolboxContainers.py +20 -293
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +6 -6
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +7 -6
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/toolboxNumba.py +2 -2
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/transformationTools.py +9 -216
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding.egg-info/PKG-INFO +2 -1
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding.egg-info/SOURCES.txt +0 -12
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding.egg-info/requires.txt +1 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/pyproject.toml +2 -1
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_astTypes.py +0 -117
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_theTypes.py +0 -34
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolBe.py +0 -524
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolDOT.py +0 -493
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolGrab.py +0 -653
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolIfThis.py +0 -193
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolMake.py +0 -339
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolThen.py +0 -63
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolboxAST.py +0 -57
- mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolboxPython.py +0 -188
- mapfolding-0.10.0/mapFolding/toolFactory/astFactory.py +0 -493
- mapfolding-0.10.0/mapFolding/toolFactory/astFactory_annex.py +0 -63
- mapfolding-0.10.0/mapFolding/toolFactory/astFactory_docstrings.py +0 -63
- {mapfolding-0.10.0 → mapfolding-0.11.1}/LICENSE +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/README.md +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/basecamp.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/beDRY.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/daoOfMapFolding.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/dataBaskets.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/datatypes.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/oeis.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/py.typed +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/__init__.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/flattened.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/hunterNumba.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/irvineJavaPort.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/jaxCount.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/jobsCompleted/__init__.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/lunnonNumpy.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/lunnonWhile.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/rotatedEntryPoint.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/RecipeJob.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/__init__.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/daoOfMapFolding.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/dataPacking.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/initializeCount.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/numbaCount.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/theorem2.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/theorem2Numba.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/syntheticModules/theorem2Trimmed.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/theDao.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/theSSOT.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/toolboxFilesystem.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding.egg-info/dependency_links.txt +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding.egg-info/entry_points.txt +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding.egg-info/top_level.txt +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/setup.cfg +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/tests/__init__.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/tests/conftest.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/tests/test_computations.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/tests/test_filesystem.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/tests/test_oeis.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/tests/test_other.py +0 -0
- {mapfolding-0.10.0 → mapfolding-0.11.1}/tests/test_tasks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: Map folding algorithm with code transformation framework for optimizing numerical computations
|
|
5
5
|
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
6
|
License: CC-BY-NC-4.0
|
|
@@ -31,6 +31,7 @@ Classifier: Typing :: Typed
|
|
|
31
31
|
Requires-Python: >=3.10
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
33
33
|
License-File: LICENSE
|
|
34
|
+
Requires-Dist: astToolkit
|
|
34
35
|
Requires-Dist: autoflake
|
|
35
36
|
Requires-Dist: cytoolz
|
|
36
37
|
Requires-Dist: more_itertools
|
|
@@ -47,38 +47,22 @@ foundation for exploring advanced code transformation techniques.
|
|
|
47
47
|
from typing import Any, TypeAlias
|
|
48
48
|
import sys
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if sys.version_info >= (3, 12):
|
|
53
|
-
from ast import (
|
|
54
|
-
ParamSpec as astDOTParamSpec,
|
|
55
|
-
type_param as astDOTtype_param,
|
|
56
|
-
TypeAlias as astDOTTypeAlias,
|
|
57
|
-
TypeVar as astDOTTypeVar,
|
|
58
|
-
TypeVarTuple as astDOTTypeVarTuple,
|
|
59
|
-
)
|
|
60
|
-
else:
|
|
61
|
-
astDOTParamSpec: TypeAlias = stuPyd
|
|
62
|
-
astDOTtype_param: TypeAlias = stuPyd
|
|
63
|
-
astDOTTypeAlias: TypeAlias = stuPyd
|
|
64
|
-
astDOTTypeVar: TypeAlias = stuPyd
|
|
65
|
-
astDOTTypeVarTuple: TypeAlias = stuPyd
|
|
50
|
+
yourPythonIsOld: TypeAlias = Any
|
|
51
|
+
# ruff: noqa: E402
|
|
66
52
|
|
|
67
53
|
if sys.version_info >= (3, 11):
|
|
68
|
-
from ast import TryStar as astDOTTryStar
|
|
69
54
|
from typing import TypedDict as TypedDict
|
|
70
55
|
from typing import NotRequired as NotRequired
|
|
71
56
|
else:
|
|
72
|
-
astDOTTryStar: TypeAlias = stuPyd
|
|
73
57
|
try:
|
|
74
58
|
from typing_extensions import TypedDict as TypedDict
|
|
75
59
|
from typing_extensions import NotRequired as NotRequired
|
|
76
60
|
except Exception:
|
|
77
|
-
TypedDict = dict[
|
|
61
|
+
TypedDict = dict[yourPythonIsOld, yourPythonIsOld]
|
|
78
62
|
from collections.abc import Iterable
|
|
79
63
|
NotRequired: TypeAlias = Iterable
|
|
80
64
|
|
|
81
|
-
from mapFolding.datatypes import (
|
|
65
|
+
from mapFolding.datatypes import (
|
|
82
66
|
Array1DElephino as Array1DElephino,
|
|
83
67
|
Array1DFoldsTotal as Array1DFoldsTotal,
|
|
84
68
|
Array1DLeavesTotal as Array1DLeavesTotal,
|
|
@@ -92,18 +76,18 @@ from mapFolding.datatypes import ( # noqa: E402
|
|
|
92
76
|
NumPyLeavesTotal as NumPyLeavesTotal,
|
|
93
77
|
)
|
|
94
78
|
|
|
95
|
-
from mapFolding.theSSOT import (
|
|
79
|
+
from mapFolding.theSSOT import (
|
|
96
80
|
ComputationState as ComputationState,
|
|
97
81
|
raiseIfNoneGitHubIssueNumber3 as raiseIfNoneGitHubIssueNumber3,
|
|
98
82
|
The as The,
|
|
99
83
|
)
|
|
100
84
|
|
|
101
|
-
from mapFolding.theDao import (
|
|
85
|
+
from mapFolding.theDao import (
|
|
102
86
|
countInitialize as countInitialize,
|
|
103
87
|
doTheNeedful as doTheNeedful,
|
|
104
88
|
)
|
|
105
89
|
|
|
106
|
-
from mapFolding.beDRY import (
|
|
90
|
+
from mapFolding.beDRY import (
|
|
107
91
|
getLeavesTotal as getLeavesTotal,
|
|
108
92
|
getTaskDivisions as getTaskDivisions,
|
|
109
93
|
outfitCountFolds as outfitCountFolds,
|
|
@@ -111,17 +95,18 @@ from mapFolding.beDRY import ( # noqa: E402
|
|
|
111
95
|
validateListDimensions as validateListDimensions,
|
|
112
96
|
)
|
|
113
97
|
|
|
114
|
-
from mapFolding.toolboxFilesystem import (
|
|
98
|
+
from mapFolding.toolboxFilesystem import (
|
|
115
99
|
getPathFilenameFoldsTotal as getPathFilenameFoldsTotal,
|
|
116
100
|
getPathRootJobDEFAULT as getPathRootJobDEFAULT,
|
|
117
101
|
saveFoldsTotal as saveFoldsTotal,
|
|
118
102
|
saveFoldsTotalFAILearly as saveFoldsTotalFAILearly,
|
|
119
|
-
writeStringToHere as writeStringToHere,
|
|
120
103
|
)
|
|
121
104
|
|
|
122
|
-
from
|
|
105
|
+
from Z0Z_tools import writeStringToHere as writeStringToHere
|
|
106
|
+
|
|
107
|
+
from mapFolding.basecamp import countFolds as countFolds
|
|
123
108
|
|
|
124
|
-
from mapFolding.oeis import (
|
|
109
|
+
from mapFolding.oeis import (
|
|
125
110
|
clearOEIScache as clearOEIScache,
|
|
126
111
|
getFoldsTotalKnown as getFoldsTotalKnown,
|
|
127
112
|
getOEISids as getOEISids,
|
{mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py
RENAMED
|
@@ -9,24 +9,24 @@ from mapFolding.someAssemblyRequired import (
|
|
|
9
9
|
IfThis,
|
|
10
10
|
IngredientsFunction,
|
|
11
11
|
IngredientsModule,
|
|
12
|
+
inlineFunctionDef,
|
|
12
13
|
LedgerOfImports,
|
|
13
14
|
Make,
|
|
14
15
|
NodeChanger,
|
|
15
16
|
NodeTourist,
|
|
16
17
|
parseLogicalPath2astModule,
|
|
17
18
|
parsePathFilename2astModule,
|
|
18
|
-
|
|
19
|
+
removeUnusedParameters,
|
|
19
20
|
str_nameDOTname,
|
|
21
|
+
Then,
|
|
22
|
+
write_astModule,
|
|
20
23
|
)
|
|
21
24
|
from mapFolding.someAssemblyRequired.toolboxNumba import decorateCallableWithNumba, parametersNumbaLight
|
|
22
25
|
from mapFolding.someAssemblyRequired.transformationTools import (
|
|
23
|
-
inlineFunctionDef,
|
|
24
26
|
removeDataclassFromFunction,
|
|
25
|
-
removeUnusedParameters,
|
|
26
27
|
shatter_dataclassesDOTdataclass,
|
|
27
28
|
unpackDataclassCallFunctionRepackDataclass,
|
|
28
|
-
|
|
29
|
-
)
|
|
29
|
+
)
|
|
30
30
|
from pathlib import PurePath
|
|
31
31
|
import ast
|
|
32
32
|
|
|
@@ -58,10 +58,7 @@ def makeInitializeGroupsOfFolds() -> None:
|
|
|
58
58
|
theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
59
59
|
|
|
60
60
|
findThis = IfThis.isWhileAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
61
|
-
doThat = Grab.testAttribute(Grab.andDoAllOf([
|
|
62
|
-
Grab.opsAttribute(Then.replaceWith([ast.Eq()])), # type: ignore
|
|
63
|
-
Grab.leftAttribute(Grab.attrAttribute(Then.replaceWith(theCountingIdentifier))) # type: ignore
|
|
64
|
-
]))
|
|
61
|
+
doThat = Grab.testAttribute(Grab.andDoAllOf([ Grab.opsAttribute(Then.replaceWith([ast.Eq()])), Grab.leftAttribute(Grab.attrAttribute(Then.replaceWith(theCountingIdentifier))) ])) # type: ignore
|
|
65
62
|
NodeChanger(findThis, doThat).visit(countInitializeIngredients.astFunctionDef.body[0])
|
|
66
63
|
|
|
67
64
|
ingredientsModule = IngredientsModule(countInitializeIngredients)
|
|
@@ -171,7 +168,7 @@ def makeTheorem2() -> PurePath:
|
|
|
171
168
|
doThat = Then.removeIt
|
|
172
169
|
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
173
170
|
|
|
174
|
-
findThis = IfThis.
|
|
171
|
+
findThis = IfThis.isAttributeNamespace_IdentifierLessThanOrEqual0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
175
172
|
doThat = Then.removeIt
|
|
176
173
|
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
177
174
|
|
|
@@ -301,7 +298,8 @@ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom) -> None:
|
|
|
301
298
|
doTheNeedful.imports.addAst(astImportFrom)
|
|
302
299
|
targetCallableIdentifier = astImportFrom.names[0].name
|
|
303
300
|
doTheNeedful = unpackDataclassCallFunctionRepackDataclass(doTheNeedful, targetCallableIdentifier, shatteredDataclass)
|
|
304
|
-
|
|
301
|
+
if astImportFrom.module is None: raise raiseIfNoneGitHubIssueNumber3
|
|
302
|
+
targetFunctionDef = extractFunctionDef(parseLogicalPath2astModule(astImportFrom.module), targetCallableIdentifier)
|
|
305
303
|
if targetFunctionDef is None: raise raiseIfNoneGitHubIssueNumber3
|
|
306
304
|
astTuple: ast.Tuple | None = NodeTourist(Be.Return, Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)
|
|
307
305
|
if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
|
|
@@ -44,45 +44,41 @@ optimizations - while maintaining the ability to verify correctness at each tran
|
|
|
44
44
|
test suite.
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
-
from
|
|
47
|
+
from astToolkit import (
|
|
48
48
|
ast_expr_Slice as ast_expr_Slice,
|
|
49
49
|
ast_Identifier as ast_Identifier,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
from mapFolding.someAssemblyRequired._astTypes import * # noqa: F403
|
|
57
|
-
|
|
58
|
-
from mapFolding.someAssemblyRequired._toolboxPython import (
|
|
50
|
+
astModuleToIngredientsFunction as astModuleToIngredientsFunction,
|
|
51
|
+
Be as Be,
|
|
52
|
+
DOT as DOT,
|
|
53
|
+
extractClassDef as extractClassDef,
|
|
54
|
+
extractFunctionDef as extractFunctionDef,
|
|
55
|
+
Grab as Grab,
|
|
59
56
|
importLogicalPath2Callable as importLogicalPath2Callable,
|
|
60
57
|
importPathFilename2Callable as importPathFilename2Callable,
|
|
58
|
+
IngredientsFunction as IngredientsFunction,
|
|
59
|
+
IngredientsModule as IngredientsModule,
|
|
60
|
+
LedgerOfImports as LedgerOfImports,
|
|
61
|
+
Make as Make,
|
|
61
62
|
NodeChanger as NodeChanger,
|
|
63
|
+
NodeORattribute as NodeORattribute,
|
|
62
64
|
NodeTourist as NodeTourist,
|
|
63
65
|
parseLogicalPath2astModule as parseLogicalPath2astModule,
|
|
64
66
|
parsePathFilename2astModule as parsePathFilename2astModule,
|
|
67
|
+
str_nameDOTname as str_nameDOTname,
|
|
68
|
+
Then as Then,
|
|
65
69
|
)
|
|
66
70
|
|
|
67
|
-
from
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
from astToolkit.transformationTools import (
|
|
72
|
+
inlineFunctionDef as inlineFunctionDef,
|
|
73
|
+
removeUnusedParameters as removeUnusedParameters,
|
|
74
|
+
unparseFindReplace as unparseFindReplace,
|
|
75
|
+
write_astModule as write_astModule,
|
|
76
|
+
)
|
|
71
77
|
|
|
72
78
|
from mapFolding.someAssemblyRequired._toolIfThis import IfThis as IfThis
|
|
73
|
-
from mapFolding.someAssemblyRequired._toolThen import Then as Then
|
|
74
79
|
|
|
75
80
|
from mapFolding.someAssemblyRequired._toolboxContainers import (
|
|
76
81
|
DeReConstructField2ast as DeReConstructField2ast,
|
|
77
|
-
IngredientsFunction as IngredientsFunction,
|
|
78
|
-
IngredientsModule as IngredientsModule,
|
|
79
|
-
LedgerOfImports as LedgerOfImports,
|
|
80
82
|
RecipeSynthesizeFlow as RecipeSynthesizeFlow,
|
|
81
83
|
ShatteredDataclass as ShatteredDataclass,
|
|
82
84
|
)
|
|
83
|
-
|
|
84
|
-
from mapFolding.someAssemblyRequired._toolboxAST import (
|
|
85
|
-
astModuleToIngredientsFunction as astModuleToIngredientsFunction,
|
|
86
|
-
extractClassDef as extractClassDef,
|
|
87
|
-
extractFunctionDef as extractFunctionDef,
|
|
88
|
-
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AST Node Predicate and Access Utilities for Pattern Matching and Traversal
|
|
3
|
+
|
|
4
|
+
This module provides utilities for accessing and matching AST nodes in a consistent way. It contains three primary
|
|
5
|
+
classes:
|
|
6
|
+
|
|
7
|
+
1. DOT: Provides consistent accessor methods for AST node attributes across different node types, simplifying the access
|
|
8
|
+
to node properties.
|
|
9
|
+
|
|
10
|
+
2. be: Offers type-guard functions that verify AST node types, enabling safe type narrowing for static type checking and
|
|
11
|
+
improving code safety.
|
|
12
|
+
|
|
13
|
+
3. ifThis: Contains predicate functions for matching AST nodes based on various criteria, enabling precise targeting of
|
|
14
|
+
nodes for analysis or transformation.
|
|
15
|
+
|
|
16
|
+
These utilities form the foundation of the pattern-matching component in the AST manipulation framework, working in
|
|
17
|
+
conjunction with the NodeChanger and NodeTourist classes to enable precise and targeted code transformations. Together,
|
|
18
|
+
they implement a declarative approach to AST manipulation that separates node identification (ifThis), type verification
|
|
19
|
+
(be), and data access (DOT).
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from astToolkit import IfThis as astToolkit_IfThis
|
|
23
|
+
from collections.abc import Callable
|
|
24
|
+
from mapFolding.someAssemblyRequired import ast_Identifier, Be
|
|
25
|
+
from typing import TypeGuard
|
|
26
|
+
import ast
|
|
27
|
+
|
|
28
|
+
class IfThis(astToolkit_IfThis):
|
|
29
|
+
"""
|
|
30
|
+
Provide predicate functions for matching and filtering AST nodes based on various criteria.
|
|
31
|
+
|
|
32
|
+
The ifThis class contains static methods that generate predicate functions used to test whether AST nodes match
|
|
33
|
+
specific criteria. These predicates can be used with NodeChanger and NodeTourist to identify and process specific
|
|
34
|
+
patterns in the AST.
|
|
35
|
+
|
|
36
|
+
The class provides predicates for matching various node types, attributes, identifiers, and structural patterns,
|
|
37
|
+
enabling precise targeting of AST elements for analysis or transformation.
|
|
38
|
+
"""
|
|
39
|
+
@staticmethod
|
|
40
|
+
def isAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
|
|
41
|
+
return lambda node: (Be.Compare(node)
|
|
42
|
+
and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
|
|
43
|
+
and Be.Gt(node.ops[0])
|
|
44
|
+
and IfThis.isConstant_value(0)(node.comparators[0]))
|
|
45
|
+
@staticmethod
|
|
46
|
+
def isIfAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.If] | bool]:
|
|
47
|
+
return lambda node: (Be.If(node)
|
|
48
|
+
and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def isWhileAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.While] | bool]:
|
|
52
|
+
return lambda node: (Be.While(node)
|
|
53
|
+
and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def isAttributeNamespace_IdentifierLessThanOrEqual0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
|
|
57
|
+
return lambda node: (Be.Compare(node)
|
|
58
|
+
and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
|
|
59
|
+
and Be.LtE(node.ops[0]))
|
{mapfolding-0.10.0 → mapfolding-0.11.1}/mapFolding/someAssemblyRequired/_toolboxContainers.py
RENAMED
|
@@ -18,294 +18,15 @@ The containers work in conjunction with transformation tools that manipulate the
|
|
|
18
18
|
specific optimizations and transformations.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
from collections import
|
|
22
|
-
from collections.abc import Callable, Sequence
|
|
21
|
+
from collections.abc import Callable
|
|
23
22
|
from copy import deepcopy
|
|
24
|
-
from
|
|
25
|
-
from mapFolding.someAssemblyRequired import ast_Identifier, DOT, IfThis, Make, NodeTourist, parseLogicalPath2astModule, str_nameDOTname, Then
|
|
23
|
+
from mapFolding.someAssemblyRequired import ast_Identifier, DOT, IfThis, Make, NodeTourist, parseLogicalPath2astModule, str_nameDOTname, Then, LedgerOfImports
|
|
26
24
|
from mapFolding.theSSOT import raiseIfNoneGitHubIssueNumber3, The
|
|
27
25
|
from pathlib import Path, PurePosixPath
|
|
28
|
-
from
|
|
26
|
+
from typing import Any, cast
|
|
29
27
|
import ast
|
|
30
28
|
import dataclasses
|
|
31
29
|
|
|
32
|
-
class LedgerOfImports:
|
|
33
|
-
"""
|
|
34
|
-
Track and manage import statements for programmatically generated code.
|
|
35
|
-
|
|
36
|
-
LedgerOfImports acts as a registry for import statements, maintaining a clean separation between the logical
|
|
37
|
-
structure of imports and their textual representation. It enables:
|
|
38
|
-
|
|
39
|
-
1. Tracking regular imports and import-from statements.
|
|
40
|
-
2. Adding imports programmatically during code transformation.
|
|
41
|
-
3. Merging imports from multiple sources.
|
|
42
|
-
4. Removing unnecessary or conflicting imports.
|
|
43
|
-
5. Generating optimized AST import nodes for the final code.
|
|
44
|
-
|
|
45
|
-
This class forms the foundation of dependency management in generated code, ensuring that all required libraries are
|
|
46
|
-
available without duplication or conflict.
|
|
47
|
-
"""
|
|
48
|
-
# TODO When resolving the ledger of imports, remove self-referential imports
|
|
49
|
-
|
|
50
|
-
def __init__(self, startWith: ast.AST | None = None, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
51
|
-
self.dictionaryImportFrom: dict[str_nameDOTname, list[tuple[ast_Identifier, ast_Identifier | None]]] = defaultdict(list)
|
|
52
|
-
self.listImport: list[str_nameDOTname] = []
|
|
53
|
-
self.type_ignores = [] if type_ignores is None else list(type_ignores)
|
|
54
|
-
if startWith:
|
|
55
|
-
self.walkThis(startWith)
|
|
56
|
-
|
|
57
|
-
def addAst(self, astImport____: ast.Import | ast.ImportFrom, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
58
|
-
match astImport____:
|
|
59
|
-
case ast.Import():
|
|
60
|
-
for alias in astImport____.names:
|
|
61
|
-
self.listImport.append(alias.name)
|
|
62
|
-
case ast.ImportFrom():
|
|
63
|
-
# TODO fix the mess created by `None` means '.'. I need a `str_nameDOTname` to replace '.'
|
|
64
|
-
if astImport____.module is None:
|
|
65
|
-
astImport____.module = '.'
|
|
66
|
-
for alias in astImport____.names:
|
|
67
|
-
self.dictionaryImportFrom[astImport____.module].append((alias.name, alias.asname))
|
|
68
|
-
case _:
|
|
69
|
-
raise ValueError(f"I received {type(astImport____) = }, but I can only accept {ast.Import} and {ast.ImportFrom}.")
|
|
70
|
-
if type_ignores:
|
|
71
|
-
self.type_ignores.extend(type_ignores)
|
|
72
|
-
|
|
73
|
-
def addImport_asStr(self, moduleWithLogicalPath: str_nameDOTname, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
74
|
-
self.listImport.append(moduleWithLogicalPath)
|
|
75
|
-
if type_ignores:
|
|
76
|
-
self.type_ignores.extend(type_ignores)
|
|
77
|
-
|
|
78
|
-
def addImportFrom_asStr(self, moduleWithLogicalPath: str_nameDOTname, name: ast_Identifier, asname: ast_Identifier | None = None, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
79
|
-
self.dictionaryImportFrom[moduleWithLogicalPath].append((name, asname))
|
|
80
|
-
if type_ignores:
|
|
81
|
-
self.type_ignores.extend(type_ignores)
|
|
82
|
-
|
|
83
|
-
def removeImportFromModule(self, moduleWithLogicalPath: str_nameDOTname) -> None:
|
|
84
|
-
"""Remove all imports from a specific module."""
|
|
85
|
-
self.removeImportFrom(moduleWithLogicalPath, None, None)
|
|
86
|
-
|
|
87
|
-
def removeImportFrom(self, moduleWithLogicalPath: str_nameDOTname, name: ast_Identifier | None, asname: ast_Identifier | None = None) -> None:
|
|
88
|
-
"""
|
|
89
|
-
name, asname Action
|
|
90
|
-
None, None : remove all matches for the module
|
|
91
|
-
ast_Identifier, ast_Identifier : remove exact matches
|
|
92
|
-
ast_Identifier, None : remove exact matches
|
|
93
|
-
None, ast_Identifier : remove all matches for asname and if entry_asname is None remove name == ast_Identifier
|
|
94
|
-
"""
|
|
95
|
-
if moduleWithLogicalPath in self.dictionaryImportFrom:
|
|
96
|
-
if name is None and asname is None:
|
|
97
|
-
# Remove all entries for the module
|
|
98
|
-
self.dictionaryImportFrom.pop(moduleWithLogicalPath)
|
|
99
|
-
else:
|
|
100
|
-
if name is None:
|
|
101
|
-
self.dictionaryImportFrom[moduleWithLogicalPath] = [(entry_name, entry_asname) for entry_name, entry_asname in self.dictionaryImportFrom[moduleWithLogicalPath]
|
|
102
|
-
if not (entry_asname == asname) and not (entry_asname is None and entry_name == asname)]
|
|
103
|
-
else:
|
|
104
|
-
self.dictionaryImportFrom[moduleWithLogicalPath] = [(entry_name, entry_asname) for entry_name, entry_asname in self.dictionaryImportFrom[moduleWithLogicalPath]
|
|
105
|
-
if not (entry_name == name and entry_asname == asname)]
|
|
106
|
-
if not self.dictionaryImportFrom[moduleWithLogicalPath]:
|
|
107
|
-
self.dictionaryImportFrom.pop(moduleWithLogicalPath)
|
|
108
|
-
|
|
109
|
-
def exportListModuleIdentifiers(self) -> list[ast_Identifier]:
|
|
110
|
-
listModuleIdentifiers: list[ast_Identifier] = list(self.dictionaryImportFrom.keys())
|
|
111
|
-
listModuleIdentifiers.extend(self.listImport)
|
|
112
|
-
return sorted(set(listModuleIdentifiers))
|
|
113
|
-
|
|
114
|
-
def makeList_ast(self) -> list[ast.ImportFrom | ast.Import]:
|
|
115
|
-
listImportFrom: list[ast.ImportFrom] = []
|
|
116
|
-
for moduleWithLogicalPath, listOfNameTuples in sorted(self.dictionaryImportFrom.items()):
|
|
117
|
-
listOfNameTuples = sorted(list(set(listOfNameTuples)), key=lambda nameTuple: nameTuple[0])
|
|
118
|
-
list_alias: list[ast.alias] = []
|
|
119
|
-
for name, asname in listOfNameTuples:
|
|
120
|
-
list_alias.append(Make.alias(name, asname))
|
|
121
|
-
if list_alias:
|
|
122
|
-
listImportFrom.append(Make.ImportFrom(moduleWithLogicalPath, list_alias))
|
|
123
|
-
list_astImport: list[ast.Import] = [Make.Import(moduleWithLogicalPath) for moduleWithLogicalPath in sorted(set(self.listImport))]
|
|
124
|
-
return listImportFrom + list_astImport
|
|
125
|
-
|
|
126
|
-
def update(self, *fromLedger: 'LedgerOfImports') -> None:
|
|
127
|
-
"""Update this ledger with imports from one or more other ledgers.
|
|
128
|
-
Parameters:
|
|
129
|
-
*fromLedger: One or more other `LedgerOfImports` objects from which to merge.
|
|
130
|
-
"""
|
|
131
|
-
updatedDictionary = updateExtendPolishDictionaryLists(self.dictionaryImportFrom, *(ledger.dictionaryImportFrom for ledger in fromLedger), destroyDuplicates=True, reorderLists=True)
|
|
132
|
-
self.dictionaryImportFrom = defaultdict(list, updatedDictionary)
|
|
133
|
-
for ledger in fromLedger:
|
|
134
|
-
self.listImport.extend(ledger.listImport)
|
|
135
|
-
self.type_ignores.extend(ledger.type_ignores)
|
|
136
|
-
|
|
137
|
-
def walkThis(self, walkThis: ast.AST, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
138
|
-
for nodeBuffalo in ast.walk(walkThis):
|
|
139
|
-
if isinstance(nodeBuffalo, (ast.Import, ast.ImportFrom)):
|
|
140
|
-
self.addAst(nodeBuffalo)
|
|
141
|
-
if type_ignores:
|
|
142
|
-
self.type_ignores.extend(type_ignores)
|
|
143
|
-
|
|
144
|
-
# Consolidate settings classes through inheritance https://github.com/hunterhogan/mapFolding/issues/15
|
|
145
|
-
@dataclasses.dataclass
|
|
146
|
-
class IngredientsFunction:
|
|
147
|
-
"""
|
|
148
|
-
Package a function definition with its import dependencies for code generation.
|
|
149
|
-
|
|
150
|
-
IngredientsFunction encapsulates an AST function definition along with all the imports required for that function to
|
|
151
|
-
operate correctly. This creates a modular, portable unit that can be:
|
|
152
|
-
|
|
153
|
-
1. Transformed independently (e.g., by applying Numba decorators).
|
|
154
|
-
2. Transplanted between modules while maintaining dependencies.
|
|
155
|
-
3. Combined with other functions to form complete modules.
|
|
156
|
-
4. Analyzed for optimization opportunities.
|
|
157
|
-
|
|
158
|
-
This class forms the primary unit of function manipulation in the code generation system, enabling targeted
|
|
159
|
-
transformations while preserving function dependencies.
|
|
160
|
-
|
|
161
|
-
Parameters:
|
|
162
|
-
astFunctionDef: The AST representation of the function definition
|
|
163
|
-
imports: Import statements needed by the function
|
|
164
|
-
type_ignores: Type ignore comments associated with the function
|
|
165
|
-
"""
|
|
166
|
-
astFunctionDef: ast.FunctionDef
|
|
167
|
-
imports: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
|
|
168
|
-
type_ignores: list[ast.TypeIgnore] = dataclasses.field(default_factory=list)
|
|
169
|
-
|
|
170
|
-
# Consolidate settings classes through inheritance https://github.com/hunterhogan/mapFolding/issues/15
|
|
171
|
-
@dataclasses.dataclass
|
|
172
|
-
class IngredientsModule:
|
|
173
|
-
"""
|
|
174
|
-
Assemble a complete Python module from its constituent AST components.
|
|
175
|
-
|
|
176
|
-
IngredientsModule provides a structured container for all elements needed to generate a complete Python module,
|
|
177
|
-
including:
|
|
178
|
-
|
|
179
|
-
1. Import statements aggregated from all module components.
|
|
180
|
-
2. Prologue code that runs before function definitions.
|
|
181
|
-
3. Function definitions with their dependencies.
|
|
182
|
-
4. Epilogue code that runs after function definitions.
|
|
183
|
-
5. Entry point code executed when the module runs as a script.
|
|
184
|
-
6. Type ignores and other annotations.
|
|
185
|
-
|
|
186
|
-
This class enables programmatic assembly of Python modules with a clear separation between different structural
|
|
187
|
-
elements, while maintaining the proper ordering and relationships between components.
|
|
188
|
-
|
|
189
|
-
The modular design allows transformations to be applied to specific parts of a module while preserving the overall
|
|
190
|
-
structure.
|
|
191
|
-
|
|
192
|
-
Parameters:
|
|
193
|
-
ingredientsFunction (None): One or more `IngredientsFunction` that will appended to `listIngredientsFunctions`.
|
|
194
|
-
"""
|
|
195
|
-
ingredientsFunction: dataclasses.InitVar[Sequence[IngredientsFunction] | IngredientsFunction | None] = None
|
|
196
|
-
|
|
197
|
-
# init var with an existing module? method to deconstruct an existing module?
|
|
198
|
-
|
|
199
|
-
# `body` attribute of `ast.Module`
|
|
200
|
-
"""NOTE
|
|
201
|
-
- Bare statements in `prologue` and `epilogue` are not 'protected' by `if __name__ == '__main__':` so they will be executed merely by loading the module.
|
|
202
|
-
- The dataclass has methods for modifying `prologue`, `epilogue`, and `launcher`.
|
|
203
|
-
- However, `prologue`, `epilogue`, and `launcher` are `ast.Module` (as opposed to `list[ast.stmt]`), so that you may use tools such as `ast.walk` and `ast.NodeVisitor` on the fields.
|
|
204
|
-
"""
|
|
205
|
-
imports: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
|
|
206
|
-
"""Modify this field using the methods in `LedgerOfImports`."""
|
|
207
|
-
prologue: ast.Module = Make.Module([],[])
|
|
208
|
-
"""Statements after the imports and before the functions in listIngredientsFunctions."""
|
|
209
|
-
listIngredientsFunctions: list[IngredientsFunction] = dataclasses.field(default_factory=list)
|
|
210
|
-
epilogue: ast.Module = Make.Module([],[])
|
|
211
|
-
"""Statements after the functions in listIngredientsFunctions and before `launcher`."""
|
|
212
|
-
launcher: ast.Module = Make.Module([],[])
|
|
213
|
-
"""`if __name__ == '__main__':`"""
|
|
214
|
-
|
|
215
|
-
# `ast.TypeIgnore` statements to supplement those in other fields; `type_ignores` is a parameter for `ast.Module` constructor
|
|
216
|
-
supplemental_type_ignores: list[ast.TypeIgnore] = dataclasses.field(default_factory=list)
|
|
217
|
-
|
|
218
|
-
def __post_init__(self, ingredientsFunction: Sequence[IngredientsFunction] | IngredientsFunction | None = None) -> None:
|
|
219
|
-
if ingredientsFunction is not None:
|
|
220
|
-
if isinstance(ingredientsFunction, IngredientsFunction):
|
|
221
|
-
self.appendIngredientsFunction(ingredientsFunction)
|
|
222
|
-
else:
|
|
223
|
-
self.appendIngredientsFunction(*ingredientsFunction)
|
|
224
|
-
|
|
225
|
-
def _append_astModule(self, self_astModule: ast.Module, astModule: ast.Module | None, statement: Sequence[ast.stmt] | ast.stmt | None, type_ignores: list[ast.TypeIgnore] | None) -> None:
|
|
226
|
-
"""Append one or more statements to `prologue`."""
|
|
227
|
-
list_body: list[ast.stmt] = []
|
|
228
|
-
listTypeIgnore: list[ast.TypeIgnore] = []
|
|
229
|
-
if astModule is not None and isinstance(astModule, ast.Module): # type: ignore
|
|
230
|
-
list_body.extend(astModule.body)
|
|
231
|
-
listTypeIgnore.extend(astModule.type_ignores)
|
|
232
|
-
if type_ignores is not None:
|
|
233
|
-
listTypeIgnore.extend(type_ignores)
|
|
234
|
-
if statement is not None:
|
|
235
|
-
if isinstance(statement, Sequence):
|
|
236
|
-
list_body.extend(statement)
|
|
237
|
-
else:
|
|
238
|
-
list_body.append(statement)
|
|
239
|
-
self_astModule.body.extend(list_body)
|
|
240
|
-
self_astModule.type_ignores.extend(listTypeIgnore)
|
|
241
|
-
ast.fix_missing_locations(self_astModule)
|
|
242
|
-
|
|
243
|
-
def appendPrologue(self, astModule: ast.Module | None = None, statement: Sequence[ast.stmt] | ast.stmt | None = None, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
244
|
-
"""Append one or more statements to `prologue`."""
|
|
245
|
-
self._append_astModule(self.prologue, astModule, statement, type_ignores)
|
|
246
|
-
|
|
247
|
-
def appendEpilogue(self, astModule: ast.Module | None = None, statement: Sequence[ast.stmt] | ast.stmt | None = None, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
248
|
-
"""Append one or more statements to `epilogue`."""
|
|
249
|
-
self._append_astModule(self.epilogue, astModule, statement, type_ignores)
|
|
250
|
-
|
|
251
|
-
def appendLauncher(self, astModule: ast.Module | None = None, statement: Sequence[ast.stmt] | ast.stmt | None = None, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
|
|
252
|
-
"""Append one or more statements to `launcher`."""
|
|
253
|
-
self._append_astModule(self.launcher, astModule, statement, type_ignores)
|
|
254
|
-
|
|
255
|
-
def appendIngredientsFunction(self, *ingredientsFunction: IngredientsFunction) -> None:
|
|
256
|
-
"""Append one or more `IngredientsFunction`."""
|
|
257
|
-
for allegedIngredientsFunction in ingredientsFunction:
|
|
258
|
-
self.listIngredientsFunctions.append(allegedIngredientsFunction)
|
|
259
|
-
|
|
260
|
-
def removeImportFromModule(self, moduleWithLogicalPath: str_nameDOTname) -> None:
|
|
261
|
-
self.removeImportFrom(moduleWithLogicalPath, None, None)
|
|
262
|
-
"""Remove all imports from a specific module."""
|
|
263
|
-
|
|
264
|
-
def removeImportFrom(self, moduleWithLogicalPath: str_nameDOTname, name: ast_Identifier | None, asname: ast_Identifier | None = None) -> None:
|
|
265
|
-
"""
|
|
266
|
-
This method modifies all `LedgerOfImports` in this `IngredientsModule` and all `IngredientsFunction` in `listIngredientsFunctions`.
|
|
267
|
-
It is not a "blacklist", so the `import from` could be added after this modification.
|
|
268
|
-
"""
|
|
269
|
-
self.imports.removeImportFrom(moduleWithLogicalPath, name, asname)
|
|
270
|
-
for ingredientsFunction in self.listIngredientsFunctions:
|
|
271
|
-
ingredientsFunction.imports.removeImportFrom(moduleWithLogicalPath, name, asname)
|
|
272
|
-
|
|
273
|
-
def _consolidatedLedger(self) -> LedgerOfImports:
|
|
274
|
-
"""Consolidate all ledgers of imports."""
|
|
275
|
-
sherpaLedger = LedgerOfImports()
|
|
276
|
-
listLedgers: list[LedgerOfImports] = [self.imports]
|
|
277
|
-
for ingredientsFunction in self.listIngredientsFunctions:
|
|
278
|
-
listLedgers.append(ingredientsFunction.imports)
|
|
279
|
-
sherpaLedger.update(*listLedgers)
|
|
280
|
-
return sherpaLedger
|
|
281
|
-
|
|
282
|
-
@property
|
|
283
|
-
def list_astImportImportFrom(self) -> list[ast.Import | ast.ImportFrom]:
|
|
284
|
-
return self._consolidatedLedger().makeList_ast()
|
|
285
|
-
|
|
286
|
-
@property
|
|
287
|
-
def body(self) -> list[ast.stmt]:
|
|
288
|
-
list_stmt: list[ast.stmt] = []
|
|
289
|
-
list_stmt.extend(self.list_astImportImportFrom)
|
|
290
|
-
list_stmt.extend(self.prologue.body)
|
|
291
|
-
for ingredientsFunction in self.listIngredientsFunctions:
|
|
292
|
-
list_stmt.append(ingredientsFunction.astFunctionDef)
|
|
293
|
-
list_stmt.extend(self.epilogue.body)
|
|
294
|
-
list_stmt.extend(self.launcher.body)
|
|
295
|
-
# TODO `launcher`, if it exists, must start with `if __name__ == '__main__':` and be indented
|
|
296
|
-
return list_stmt
|
|
297
|
-
|
|
298
|
-
@property
|
|
299
|
-
def type_ignores(self) -> list[ast.TypeIgnore]:
|
|
300
|
-
listTypeIgnore: list[ast.TypeIgnore] = self.supplemental_type_ignores
|
|
301
|
-
listTypeIgnore.extend(self._consolidatedLedger().type_ignores)
|
|
302
|
-
listTypeIgnore.extend(self.prologue.type_ignores)
|
|
303
|
-
for ingredientsFunction in self.listIngredientsFunctions:
|
|
304
|
-
listTypeIgnore.extend(ingredientsFunction.type_ignores)
|
|
305
|
-
listTypeIgnore.extend(self.epilogue.type_ignores)
|
|
306
|
-
listTypeIgnore.extend(self.launcher.type_ignores)
|
|
307
|
-
return listTypeIgnore
|
|
308
|
-
|
|
309
30
|
# Consolidate settings classes through inheritance https://github.com/hunterhogan/mapFolding/issues/15
|
|
310
31
|
@dataclasses.dataclass
|
|
311
32
|
class RecipeSynthesizeFlow:
|
|
@@ -436,10 +157,10 @@ class ShatteredDataclass:
|
|
|
436
157
|
countingVariableName: ast.Name
|
|
437
158
|
"""AST name node representing the counting variable identifier."""
|
|
438
159
|
|
|
439
|
-
field2AnnAssign: dict[ast_Identifier, ast.AnnAssign | ast.Assign] = dataclasses.field(default_factory=dict)
|
|
160
|
+
field2AnnAssign: dict[ast_Identifier, ast.AnnAssign | ast.Assign] = dataclasses.field(default_factory=lambda: dict[ast_Identifier, ast.AnnAssign | ast.Assign]())
|
|
440
161
|
"""Maps field names to their corresponding AST call expressions."""
|
|
441
162
|
|
|
442
|
-
Z0Z_field2AnnAssign: dict[ast_Identifier, tuple[ast.AnnAssign | ast.Assign, str]] = dataclasses.field(default_factory=dict)
|
|
163
|
+
Z0Z_field2AnnAssign: dict[ast_Identifier, tuple[ast.AnnAssign | ast.Assign, str]] = dataclasses.field(default_factory=lambda: dict[ast_Identifier, tuple[ast.AnnAssign | ast.Assign, str]]())
|
|
443
164
|
|
|
444
165
|
fragments4AssignmentOrParameters: ast.Tuple = dummyTuple
|
|
445
166
|
"""AST tuple used as target for assignment to capture returned fragments."""
|
|
@@ -447,22 +168,22 @@ class ShatteredDataclass:
|
|
|
447
168
|
imports: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
|
|
448
169
|
"""Import records for the dataclass and its constituent parts."""
|
|
449
170
|
|
|
450
|
-
list_argAnnotated4ArgumentsSpecification: list[ast.arg] = dataclasses.field(default_factory=list)
|
|
171
|
+
list_argAnnotated4ArgumentsSpecification: list[ast.arg] = dataclasses.field(default_factory=lambda: list[ast.arg]())
|
|
451
172
|
"""Function argument nodes with annotations for parameter specification."""
|
|
452
173
|
|
|
453
|
-
list_keyword_field__field4init: list[ast.keyword] = dataclasses.field(default_factory=list)
|
|
174
|
+
list_keyword_field__field4init: list[ast.keyword] = dataclasses.field(default_factory=lambda: list[ast.keyword]())
|
|
454
175
|
"""Keyword arguments for dataclass initialization with field=field format."""
|
|
455
176
|
|
|
456
|
-
listAnnotations: list[ast.expr] = dataclasses.field(default_factory=list)
|
|
177
|
+
listAnnotations: list[ast.expr] = dataclasses.field(default_factory=lambda: list[ast.expr]())
|
|
457
178
|
"""Type annotations for each dataclass field."""
|
|
458
179
|
|
|
459
|
-
listName4Parameters: list[ast.Name] = dataclasses.field(default_factory=list)
|
|
180
|
+
listName4Parameters: list[ast.Name] = dataclasses.field(default_factory=lambda: list[ast.Name]())
|
|
460
181
|
"""Name nodes for each dataclass field used as function parameters."""
|
|
461
182
|
|
|
462
|
-
listUnpack: list[ast.AnnAssign] = dataclasses.field(default_factory=list)
|
|
183
|
+
listUnpack: list[ast.AnnAssign] = dataclasses.field(default_factory=lambda: list[ast.AnnAssign]())
|
|
463
184
|
"""Annotated assignment statements to extract fields from dataclass."""
|
|
464
185
|
|
|
465
|
-
map_stateDOTfield2Name: dict[ast.AST, ast.Name] = dataclasses.field(default_factory=dict)
|
|
186
|
+
map_stateDOTfield2Name: dict[ast.AST, ast.Name] = dataclasses.field(default_factory=lambda: dict[ast.AST, ast.Name]())
|
|
466
187
|
"""Maps AST expressions to Name nodes for find-replace operations."""
|
|
467
188
|
|
|
468
189
|
repack: ast.Assign = dummyAssign
|
|
@@ -531,7 +252,13 @@ class DeReConstructField2ast:
|
|
|
531
252
|
self.ast_keyword_field__field = Make.keyword(self.name, self.astName)
|
|
532
253
|
self.ast_nameDOTname = Make.Attribute(Make.Name(dataclassesDOTdataclassInstance_Identifier), self.name)
|
|
533
254
|
|
|
534
|
-
|
|
255
|
+
findThis = IfThis.isAnnAssign_targetIs(IfThis.isName_Identifier(self.name))
|
|
256
|
+
|
|
257
|
+
sherpa = NodeTourist(
|
|
258
|
+
findThis=findThis
|
|
259
|
+
, doThat=Then.extractIt(DOT.annotation)
|
|
260
|
+
).captureLastMatch(dataclassClassDef)
|
|
261
|
+
|
|
535
262
|
if sherpa is None: raise raiseIfNoneGitHubIssueNumber3
|
|
536
263
|
else: self.astAnnotation = sherpa
|
|
537
264
|
|
|
@@ -544,7 +271,7 @@ class DeReConstructField2ast:
|
|
|
544
271
|
self.ledger.addImportFrom_asStr(moduleWithLogicalPath, annotationType)
|
|
545
272
|
self.ledger.addImportFrom_asStr(moduleWithLogicalPath, 'dtype')
|
|
546
273
|
axesSubscript = Make.Subscript(Make.Name('tuple'), Make.Name('uint8'))
|
|
547
|
-
dtype_asnameName: ast.Name = self.astAnnotation
|
|
274
|
+
dtype_asnameName: ast.Name = cast(ast.Name, self.astAnnotation)
|
|
548
275
|
if dtype_asnameName.id == 'Array3D':
|
|
549
276
|
axesSubscript = Make.Subscript(Make.Name('tuple'), Make.Tuple([Make.Name('uint8'), Make.Name('uint8'), Make.Name('uint8')]))
|
|
550
277
|
ast_expr = Make.Subscript(Make.Name(annotationType), Make.Tuple([axesSubscript, Make.Subscript(Make.Name('dtype'), dtype_asnameName)]))
|
|
@@ -561,7 +288,7 @@ class DeReConstructField2ast:
|
|
|
561
288
|
elif isinstance(self.astAnnotation, ast.Subscript):
|
|
562
289
|
elementConstructor: ast_Identifier = self.metadata['elementConstructor']
|
|
563
290
|
self.ledger.addImportFrom_asStr(dataclassesDOTdataclassLogicalPathModule, elementConstructor)
|
|
564
|
-
takeTheTuple
|
|
291
|
+
takeTheTuple = deepcopy(self.astAnnotation.slice)
|
|
565
292
|
self.astAnnAssignConstructor = Make.AnnAssign(self.astName, self.astAnnotation, takeTheTuple)
|
|
566
293
|
self.Z0Z_hack = (self.astAnnAssignConstructor, elementConstructor)
|
|
567
294
|
if isinstance(self.astAnnotation, ast.Name):
|