mapFolding 0.7.0__py3-none-any.whl → 0.8.0__py3-none-any.whl
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/__init__.py +1 -1
- mapFolding/basecamp.py +2 -2
- mapFolding/beDRY.py +88 -85
- mapFolding/filesystem.py +37 -29
- mapFolding/noHomeYet.py +2 -2
- mapFolding/oeis.py +2 -2
- mapFolding/someAssemblyRequired/Z0Z_workbench.py +347 -31
- mapFolding/someAssemblyRequired/__init__.py +4 -3
- mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -1
- mapFolding/someAssemblyRequired/ingredientsNumba.py +87 -2
- mapFolding/someAssemblyRequired/synthesizeDataConverters.py +34 -52
- mapFolding/someAssemblyRequired/{synthesizeNumbaJob.py → synthesizeNumbaJobVESTIGIAL.py} +18 -21
- mapFolding/someAssemblyRequired/transformationTools.py +547 -209
- mapFolding/syntheticModules/numbaCount_doTheNeedful.py +197 -12
- mapFolding/theDao.py +57 -39
- mapFolding/theSSOT.py +59 -59
- {mapfolding-0.7.0.dist-info → mapfolding-0.8.0.dist-info}/METADATA +6 -7
- mapfolding-0.8.0.dist-info/RECORD +41 -0
- {mapfolding-0.7.0.dist-info → mapfolding-0.8.0.dist-info}/WHEEL +1 -1
- tests/conftest.py +2 -3
- tests/test_computations.py +9 -5
- tests/test_filesystem.py +0 -2
- tests/test_other.py +2 -3
- tests/test_tasks.py +7 -5
- mapFolding/someAssemblyRequired/synthesizeCountingFunctions.py +0 -7
- mapFolding/someAssemblyRequired/synthesizeNumba.py +0 -91
- mapFolding/someAssemblyRequired/synthesizeNumbaModules.py +0 -91
- mapFolding/someAssemblyRequired/whatWillBe.py +0 -311
- mapFolding/syntheticModules/__init__.py +0 -0
- mapFolding/syntheticModules/dataNamespaceFlattened.py +0 -30
- mapFolding/syntheticModules/numbaCount.py +0 -90
- mapFolding/syntheticModules/numbaCountSequential.py +0 -110
- mapFolding/syntheticModules/numba_doTheNeedful.py +0 -12
- mapfolding-0.7.0.dist-info/RECORD +0 -50
- /mapFolding/syntheticModules/{numbaCountExample.py → numbaCountHistoricalExample.py} +0 -0
- /mapFolding/syntheticModules/{numba_doTheNeedfulExample.py → numba_doTheNeedfulHistoricalExample.py} +0 -0
- {mapfolding-0.7.0.dist-info → mapfolding-0.8.0.dist-info}/LICENSE +0 -0
- {mapfolding-0.7.0.dist-info → mapfolding-0.8.0.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.7.0.dist-info → mapfolding-0.8.0.dist-info}/top_level.txt +0 -0
|
@@ -1,34 +1,350 @@
|
|
|
1
|
-
from
|
|
2
|
-
from mapFolding.
|
|
3
|
-
from mapFolding.someAssemblyRequired
|
|
4
|
-
|
|
1
|
+
from autoflake import fix_code as autoflake_fix_code
|
|
2
|
+
from mapFolding.filesystem import writeStringToHere
|
|
3
|
+
from mapFolding.someAssemblyRequired import (
|
|
4
|
+
ast_Identifier,
|
|
5
|
+
extractFunctionDef,
|
|
6
|
+
ifThis,
|
|
7
|
+
IngredientsFunction,
|
|
8
|
+
IngredientsModule,
|
|
9
|
+
LedgerOfImports,
|
|
10
|
+
Make,
|
|
11
|
+
makeDictionaryReplacementStatements,
|
|
12
|
+
NodeCollector,
|
|
13
|
+
NodeReplacer,
|
|
14
|
+
RecipeSynthesizeFlow,
|
|
15
|
+
strDotStrCuzPyStoopid,
|
|
16
|
+
Then,
|
|
17
|
+
)
|
|
18
|
+
from mapFolding.someAssemblyRequired.ingredientsNumba import decorateCallableWithNumba
|
|
19
|
+
from mapFolding.someAssemblyRequired.synthesizeDataConverters import shatter_dataclassesDOTdataclass
|
|
20
|
+
from mapFolding.theSSOT import raiseIfNoneGitHubIssueNumber3
|
|
21
|
+
from pathlib import Path
|
|
5
22
|
import ast
|
|
6
23
|
|
|
24
|
+
# Would `LibCST` be better than `ast` in some cases? https://github.com/hunterhogan/mapFolding/issues/7
|
|
25
|
+
|
|
26
|
+
def Z0Z_alphaTest_putModuleOnDisk(ingredients: IngredientsModule, recipeFlow: RecipeSynthesizeFlow):
|
|
27
|
+
# Physical namespace
|
|
28
|
+
filenameStem: str = recipeFlow.moduleDispatcher
|
|
29
|
+
fileExtension: str = recipeFlow.fileExtension
|
|
30
|
+
pathPackage: Path = Path(recipeFlow.pathPackage)
|
|
31
|
+
|
|
32
|
+
# Physical and logical namespace
|
|
33
|
+
packageName: ast_Identifier | None = recipeFlow.packageName # module name of the package, if any
|
|
34
|
+
logicalPathINFIX: ast_Identifier | strDotStrCuzPyStoopid | None = recipeFlow.Z0Z_flowLogicalPathRoot
|
|
35
|
+
|
|
36
|
+
def _getLogicalPathParent() -> str | None:
|
|
37
|
+
listModules: list[ast_Identifier] = []
|
|
38
|
+
if packageName:
|
|
39
|
+
listModules.append(packageName)
|
|
40
|
+
if logicalPathINFIX:
|
|
41
|
+
listModules.append(logicalPathINFIX)
|
|
42
|
+
if listModules:
|
|
43
|
+
return '.'.join(listModules)
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
def _getLogicalPathAbsolute() -> str:
|
|
47
|
+
listModules: list[ast_Identifier] = []
|
|
48
|
+
logicalPathParent: str | None = _getLogicalPathParent()
|
|
49
|
+
if logicalPathParent:
|
|
50
|
+
listModules.append(logicalPathParent)
|
|
51
|
+
listModules.append(filenameStem)
|
|
52
|
+
return '.'.join(listModules)
|
|
53
|
+
|
|
54
|
+
def getPathFilename():
|
|
55
|
+
pathRoot: Path = pathPackage
|
|
56
|
+
filename: str = filenameStem + fileExtension
|
|
57
|
+
if logicalPathINFIX:
|
|
58
|
+
whyIsThisStillAThing: list[str] = logicalPathINFIX.split('.')
|
|
59
|
+
pathRoot = pathRoot.joinpath(*whyIsThisStillAThing)
|
|
60
|
+
return pathRoot.joinpath(filename)
|
|
61
|
+
|
|
62
|
+
def absoluteImport() -> ast.Import:
|
|
63
|
+
return Make.astImport(_getLogicalPathAbsolute())
|
|
64
|
+
|
|
65
|
+
def absoluteImportFrom() -> ast.ImportFrom:
|
|
66
|
+
""" `from . import theModule` """
|
|
67
|
+
logicalPathParent: str = _getLogicalPathParent() or '.'
|
|
68
|
+
return Make.astImportFrom(logicalPathParent, [Make.astAlias(filenameStem)])
|
|
69
|
+
|
|
70
|
+
def writeModule() -> None:
|
|
71
|
+
astModule = ingredients.export()
|
|
72
|
+
ast.fix_missing_locations(astModule)
|
|
73
|
+
pythonSource: str = ast.unparse(astModule)
|
|
74
|
+
if not pythonSource: raise raiseIfNoneGitHubIssueNumber3
|
|
75
|
+
autoflake_additional_imports: list[str] = ingredients.imports.exportListModuleNames()
|
|
76
|
+
if packageName:
|
|
77
|
+
autoflake_additional_imports.append(packageName)
|
|
78
|
+
pythonSource = autoflake_fix_code(pythonSource, autoflake_additional_imports, expand_star_imports=False, remove_all_unused_imports=False, remove_duplicate_keys = False, remove_unused_variables = False,)
|
|
79
|
+
pathFilename = getPathFilename()
|
|
80
|
+
writeStringToHere(pythonSource, pathFilename)
|
|
81
|
+
|
|
82
|
+
writeModule()
|
|
83
|
+
|
|
84
|
+
def inlineThisFunctionWithTheseValues(astFunctionDef: ast.FunctionDef, dictionaryReplacementStatements: dict[str, ast.stmt | list[ast.stmt]]) -> ast.FunctionDef:
|
|
85
|
+
class FunctionInliner(ast.NodeTransformer):
|
|
86
|
+
def __init__(self, dictionaryReplacementStatements: dict[str, ast.stmt | list[ast.stmt]]) -> None:
|
|
87
|
+
self.dictionaryReplacementStatements = dictionaryReplacementStatements
|
|
88
|
+
|
|
89
|
+
def generic_visit(self, node: ast.AST) -> ast.AST:
|
|
90
|
+
"""Visit all nodes and replace them if necessary."""
|
|
91
|
+
return super().generic_visit(node)
|
|
92
|
+
|
|
93
|
+
def visit_Expr(self, node: ast.Expr) -> ast.AST | list[ast.stmt]:
|
|
94
|
+
"""Visit Expr nodes and replace value if it's a function call in our dictionary."""
|
|
95
|
+
if ifThis.CallDoesNotCallItselfAndNameDOTidIsIn(self.dictionaryReplacementStatements)(node.value):
|
|
96
|
+
return self.dictionaryReplacementStatements[node.value.func.id] # type: ignore[attr-defined]
|
|
97
|
+
return node
|
|
98
|
+
|
|
99
|
+
def visit_Assign(self, node: ast.Assign) -> ast.AST | list[ast.stmt]:
|
|
100
|
+
"""Visit Assign nodes and replace value if it's a function call in our dictionary."""
|
|
101
|
+
if ifThis.CallDoesNotCallItselfAndNameDOTidIsIn(self.dictionaryReplacementStatements)(node.value):
|
|
102
|
+
return self.dictionaryReplacementStatements[node.value.func.id] # type: ignore[attr-defined]
|
|
103
|
+
return node
|
|
104
|
+
|
|
105
|
+
def visit_Call(self, node: ast.Call) -> ast.AST | list[ast.stmt]:
|
|
106
|
+
"""Replace call nodes with their replacement statements if they're in the dictionary."""
|
|
107
|
+
if ifThis.CallDoesNotCallItselfAndNameDOTidIsIn(self.dictionaryReplacementStatements)(node):
|
|
108
|
+
replacement = self.dictionaryReplacementStatements[node.func.id] # type: ignore[attr-defined]
|
|
109
|
+
if not isinstance(replacement, list):
|
|
110
|
+
return replacement
|
|
111
|
+
return node
|
|
112
|
+
|
|
113
|
+
import copy
|
|
114
|
+
keepGoing = True
|
|
115
|
+
ImaInlineFunction = copy.deepcopy(astFunctionDef)
|
|
116
|
+
while keepGoing:
|
|
117
|
+
ImaInlineFunction = copy.deepcopy(astFunctionDef)
|
|
118
|
+
FunctionInliner(copy.deepcopy(dictionaryReplacementStatements)).visit(ImaInlineFunction)
|
|
119
|
+
if ast.unparse(ImaInlineFunction) == ast.unparse(astFunctionDef):
|
|
120
|
+
keepGoing = False
|
|
121
|
+
else:
|
|
122
|
+
astFunctionDef = copy.deepcopy(ImaInlineFunction)
|
|
123
|
+
return ImaInlineFunction
|
|
124
|
+
|
|
125
|
+
def replaceMatchingASTnodes(astTree: ast.AST, replacementMap: list[tuple[ast.AST, ast.AST]]) -> ast.AST:
|
|
126
|
+
"""Replace matching AST nodes using type-specific visitors.
|
|
127
|
+
|
|
128
|
+
Parameters:
|
|
129
|
+
astTree: The AST to transform
|
|
130
|
+
replacementMap: List of (find, replace) node pairs
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
The transformed AST
|
|
134
|
+
"""
|
|
135
|
+
class TargetedNodeReplacer(ast.NodeTransformer):
|
|
136
|
+
def __init__(self, replacementMap: list[tuple[ast.AST, ast.AST]]) -> None:
|
|
137
|
+
# Group replacements by node type for more efficient lookups
|
|
138
|
+
self.replacementByType: dict[type[ast.AST], list[tuple[ast.AST, ast.AST]]] = {}
|
|
139
|
+
for findNode, replaceNode in replacementMap:
|
|
140
|
+
nodeType = type(findNode)
|
|
141
|
+
if nodeType not in self.replacementByType:
|
|
142
|
+
self.replacementByType[nodeType] = []
|
|
143
|
+
self.replacementByType[nodeType].append((findNode, replaceNode))
|
|
144
|
+
|
|
145
|
+
def visit(self, node: ast.AST) -> ast.AST:
|
|
146
|
+
"""Check if this node should be replaced before continuing traversal."""
|
|
147
|
+
nodeType = type(node)
|
|
148
|
+
if nodeType in self.replacementByType:
|
|
149
|
+
for findNode, replaceNode in self.replacementByType[nodeType]:
|
|
150
|
+
if self.nodesMatchStructurally(node, findNode):
|
|
151
|
+
return replaceNode
|
|
152
|
+
return super().visit(node)
|
|
153
|
+
|
|
154
|
+
def nodesMatchStructurally(self, node1: ast.AST | list, node2: ast.AST | list) -> bool:
|
|
155
|
+
"""Compare two AST nodes structurally, ignoring position information."""
|
|
156
|
+
# Different types can't be equal
|
|
157
|
+
if type(node1) != type(node2):
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
if isinstance(node1, ast.AST):
|
|
161
|
+
# Compare fields that matter for structural equality
|
|
162
|
+
fields = [f for f in node1._fields
|
|
163
|
+
if f not in ('lineno', 'col_offset', 'end_lineno', 'end_col_offset', 'ctx')]
|
|
164
|
+
|
|
165
|
+
for field in fields:
|
|
166
|
+
smurf1 = getattr(node1, field, None)
|
|
167
|
+
smurf2 = getattr(node2, field, None)
|
|
168
|
+
|
|
169
|
+
if isinstance(smurf1, (ast.AST, list)) and isinstance(smurf2, (ast.AST, list)):
|
|
170
|
+
if not self.nodesMatchStructurally(smurf1, smurf2):
|
|
171
|
+
return False
|
|
172
|
+
elif smurf1 != smurf2:
|
|
173
|
+
return False
|
|
174
|
+
return True
|
|
175
|
+
|
|
176
|
+
elif isinstance(node1, list) and isinstance(node2, list):
|
|
177
|
+
if len(node1) != len(node2):
|
|
178
|
+
return False
|
|
179
|
+
return all(self.nodesMatchStructurally(x, y) for x, y in zip(node1, node2))
|
|
180
|
+
|
|
181
|
+
else:
|
|
182
|
+
# Direct comparison for non-AST objects (strings, numbers, etc.)
|
|
183
|
+
return node1 == node2
|
|
184
|
+
|
|
185
|
+
import copy
|
|
186
|
+
keepGoing = True
|
|
187
|
+
astResult = copy.deepcopy(astTree)
|
|
188
|
+
|
|
189
|
+
while keepGoing:
|
|
190
|
+
astBeforeChange = copy.deepcopy(astResult)
|
|
191
|
+
TargetedNodeReplacer(copy.deepcopy(replacementMap)).visit(astResult)
|
|
192
|
+
|
|
193
|
+
# Check if we've reached a fixed point (no more changes)
|
|
194
|
+
if ast.unparse(astResult) == ast.unparse(astBeforeChange):
|
|
195
|
+
keepGoing = False
|
|
196
|
+
|
|
197
|
+
return astResult
|
|
198
|
+
|
|
199
|
+
def Z0Z_main() -> None:
|
|
200
|
+
numbaFlow: RecipeSynthesizeFlow = RecipeSynthesizeFlow()
|
|
201
|
+
dictionaryReplacementStatements = makeDictionaryReplacementStatements(numbaFlow.source_astModule)
|
|
202
|
+
# TODO remove hardcoding
|
|
203
|
+
theCountingIdentifierHARDCODED = 'groupsOfFolds'
|
|
204
|
+
theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
205
|
+
|
|
206
|
+
# TODO remember that `sequentialCallable` and `sourceSequentialCallable` are two different values.
|
|
207
|
+
# Figure out dynamic flow control to synthesized modules https://github.com/hunterhogan/mapFolding/issues/4
|
|
208
|
+
|
|
209
|
+
# ===========================================================
|
|
210
|
+
sourcePython = numbaFlow.sourceDispatcherCallable
|
|
211
|
+
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
212
|
+
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
213
|
+
ingredientsDispatcher = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
214
|
+
|
|
215
|
+
# sourceParallelCallable
|
|
216
|
+
(astName_dataclassesDOTdataclass, ledgerDataclassANDFragments, listAnnAssign4DataclassUnpack,
|
|
217
|
+
astTuple4AssignTargetsToFragments, listNameDataclassFragments4Parameters, list_ast_argAnnotated4ArgumentsSpecification,
|
|
218
|
+
astSubscriptPrimitiveTupleAnnotations4FunctionDef_returns, astAssignDataclassRepack, list_keyword4DataclassInitialization) = shatter_dataclassesDOTdataclass(
|
|
219
|
+
numbaFlow.logicalPathModuleDataclass, numbaFlow.sourceDataclassIdentifier, numbaFlow.sourceDataclassInstanceTaskDistribution)
|
|
220
|
+
ingredientsDispatcher.imports.update(ledgerDataclassANDFragments)
|
|
221
|
+
|
|
222
|
+
# TODO remove hardcoding
|
|
223
|
+
namespaceHARDCODED = 'concurrencyManager'
|
|
224
|
+
identifierHARDCODED = 'submit'
|
|
225
|
+
namespace = namespaceHARDCODED
|
|
226
|
+
identifier = identifierHARDCODED
|
|
227
|
+
NodeReplacer(
|
|
228
|
+
findThis = ifThis.isAssignAndValueIsCallNamespace_Identifier(namespace, identifier)
|
|
229
|
+
, doThat = Then.insertThisAbove(listAnnAssign4DataclassUnpack)
|
|
230
|
+
).visit(ingredientsDispatcher.astFunctionDef)
|
|
231
|
+
NodeReplacer(
|
|
232
|
+
findThis = ifThis.isCallNamespace_Identifier(namespace, identifier)
|
|
233
|
+
, doThat = Then.replaceWith(Make.astCall(Make.astAttribute(Make.astName(namespace), identifier)
|
|
234
|
+
, listArguments=[Make.astName(numbaFlow.parallelCallable)] + listNameDataclassFragments4Parameters))
|
|
235
|
+
).visit(ingredientsDispatcher.astFunctionDef)
|
|
236
|
+
|
|
237
|
+
CapturedAssign: list[ast.AST] = []
|
|
238
|
+
CapturedCall: list[ast.Call] = []
|
|
239
|
+
findThis = ifThis.isCall
|
|
240
|
+
doThat = [Then.appendTo(CapturedCall)]
|
|
241
|
+
capture = NodeCollector(findThis, doThat)
|
|
242
|
+
|
|
243
|
+
NodeCollector(
|
|
244
|
+
findThis = ifThis.isAssignAndTargets0Is(ifThis.isSubscript_Identifier(numbaFlow.sourceDataclassInstance))
|
|
245
|
+
, doThat = [Then.appendTo(CapturedAssign)
|
|
246
|
+
, lambda node: capture.visit(node)]
|
|
247
|
+
).visit(ingredientsDispatcher.astFunctionDef)
|
|
248
|
+
|
|
249
|
+
newAssign = CapturedAssign[0]
|
|
250
|
+
NodeReplacer(
|
|
251
|
+
findThis = lambda node: ifThis.isSubscript(node) and ifThis.isAttribute(node.value) and ifThis.isCall(node.value.value)
|
|
252
|
+
, doThat = Then.replaceWith(CapturedCall[0])
|
|
253
|
+
).visit(newAssign)
|
|
254
|
+
|
|
255
|
+
NodeReplacer(
|
|
256
|
+
findThis = ifThis.isAssignAndTargets0Is(ifThis.isSubscript_Identifier(numbaFlow.sourceDataclassInstance))
|
|
257
|
+
, doThat = Then.replaceWith(newAssign)
|
|
258
|
+
).visit(ingredientsDispatcher.astFunctionDef)
|
|
259
|
+
|
|
260
|
+
# sourceSequentialCallable
|
|
261
|
+
(astName_dataclassesDOTdataclass, ledgerDataclassANDFragments, listAnnAssign4DataclassUnpack,
|
|
262
|
+
astTuple4AssignTargetsToFragments, listNameDataclassFragments4Parameters, list_ast_argAnnotated4ArgumentsSpecification,
|
|
263
|
+
astSubscriptPrimitiveTupleAnnotations4FunctionDef_returns, astAssignDataclassRepack, list_keyword4DataclassInitialization) = shatter_dataclassesDOTdataclass(
|
|
264
|
+
numbaFlow.logicalPathModuleDataclass, numbaFlow.sourceDataclassIdentifier, numbaFlow.sourceDataclassInstance)
|
|
265
|
+
ingredientsDispatcher.imports.update(ledgerDataclassANDFragments)
|
|
266
|
+
|
|
267
|
+
NodeReplacer(
|
|
268
|
+
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable)
|
|
269
|
+
, doThat = Then.insertThisAbove(listAnnAssign4DataclassUnpack)
|
|
270
|
+
).visit(ingredientsDispatcher.astFunctionDef)
|
|
271
|
+
NodeReplacer(
|
|
272
|
+
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable)
|
|
273
|
+
# findThis = ifThis.isReturn
|
|
274
|
+
, doThat = Then.insertThisBelow([astAssignDataclassRepack])
|
|
275
|
+
).visit(ingredientsDispatcher.astFunctionDef)
|
|
276
|
+
# TODO reconsider: This calls a function, but I don't inspect the function for its parameters or return.
|
|
277
|
+
NodeReplacer(
|
|
278
|
+
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable)
|
|
279
|
+
, doThat = Then.replaceWith(Make.astAssign(listTargets=[astTuple4AssignTargetsToFragments], value=Make.astCall(Make.astName(numbaFlow.sequentialCallable), listNameDataclassFragments4Parameters)))
|
|
280
|
+
).visit(ingredientsDispatcher.astFunctionDef)
|
|
281
|
+
|
|
282
|
+
# ===========================================================
|
|
283
|
+
sourcePython = numbaFlow.sourceInitializeCallable
|
|
284
|
+
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
285
|
+
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
286
|
+
astFunctionDef = inlineThisFunctionWithTheseValues(astFunctionDef, dictionaryReplacementStatements)
|
|
287
|
+
ingredientsInitialize = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
288
|
+
|
|
289
|
+
# ===========================================================
|
|
290
|
+
sourcePython = numbaFlow.sourceParallelCallable
|
|
291
|
+
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
292
|
+
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
293
|
+
astFunctionDef = inlineThisFunctionWithTheseValues(astFunctionDef, dictionaryReplacementStatements)
|
|
294
|
+
ingredientsParallel = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
295
|
+
ingredientsParallel.astFunctionDef.name = numbaFlow.parallelCallable
|
|
296
|
+
ingredientsParallel.astFunctionDef.args = Make.astArgumentsSpecification(args=list_ast_argAnnotated4ArgumentsSpecification)
|
|
297
|
+
NodeReplacer(
|
|
298
|
+
findThis = ifThis.isReturn
|
|
299
|
+
, doThat = Then.replaceWith(Make.astReturn(astTuple4AssignTargetsToFragments))
|
|
300
|
+
).visit(ingredientsParallel.astFunctionDef)
|
|
301
|
+
NodeReplacer(
|
|
302
|
+
findThis = ifThis.isReturn
|
|
303
|
+
# , doThat = Then.replaceWith(Make.astReturn(astTuple4AssignTargetsToFragments))
|
|
304
|
+
, doThat = Then.replaceWith(Make.astReturn(Make.astName(theCountingIdentifier)))
|
|
305
|
+
).visit(ingredientsParallel.astFunctionDef)
|
|
306
|
+
theCountingIdentifierAnnotation = next(
|
|
307
|
+
ast_arg.annotation for ast_arg in list_ast_argAnnotated4ArgumentsSpecification if ast_arg.arg == theCountingIdentifier)
|
|
308
|
+
ingredientsParallel.astFunctionDef.returns = theCountingIdentifierAnnotation
|
|
309
|
+
# ingredientsParallel.astFunctionDef.returns = astSubscriptPrimitiveTupleAnnotations4FunctionDef_returns
|
|
310
|
+
replacementMap = [(statement.value, statement.target) for statement in listAnnAssign4DataclassUnpack]
|
|
311
|
+
ingredientsParallel.astFunctionDef = replaceMatchingASTnodes(
|
|
312
|
+
ingredientsParallel.astFunctionDef, replacementMap) # type: ignore
|
|
313
|
+
# TODO a tool to automatically remove unused variables from the ArgumentsSpecification (return, and returns) _might_ be nice.
|
|
314
|
+
# But, I would need to update the calling function, too.
|
|
315
|
+
ingredientsParallel = decorateCallableWithNumba(ingredientsParallel) # parametersNumbaParallelDEFAULT
|
|
316
|
+
|
|
317
|
+
# ===========================================================
|
|
318
|
+
sourcePython = numbaFlow.sourceSequentialCallable
|
|
319
|
+
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
320
|
+
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
321
|
+
astFunctionDef = inlineThisFunctionWithTheseValues(astFunctionDef, dictionaryReplacementStatements)
|
|
322
|
+
ingredientsSequential = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
323
|
+
ingredientsSequential.astFunctionDef.name = numbaFlow.sequentialCallable
|
|
324
|
+
ingredientsSequential.astFunctionDef.args = Make.astArgumentsSpecification(args=list_ast_argAnnotated4ArgumentsSpecification)
|
|
325
|
+
NodeReplacer(
|
|
326
|
+
findThis = ifThis.isReturn
|
|
327
|
+
, doThat = Then.replaceWith(Make.astReturn(astTuple4AssignTargetsToFragments))
|
|
328
|
+
).visit(ingredientsSequential.astFunctionDef)
|
|
329
|
+
NodeReplacer(
|
|
330
|
+
findThis = ifThis.isReturn
|
|
331
|
+
, doThat = Then.replaceWith(Make.astReturn(astTuple4AssignTargetsToFragments))
|
|
332
|
+
).visit(ingredientsSequential.astFunctionDef)
|
|
333
|
+
ingredientsSequential.astFunctionDef.returns = astSubscriptPrimitiveTupleAnnotations4FunctionDef_returns
|
|
334
|
+
replacementMap = [(statement.value, statement.target) for statement in listAnnAssign4DataclassUnpack]
|
|
335
|
+
ingredientsSequential.astFunctionDef = replaceMatchingASTnodes(
|
|
336
|
+
ingredientsSequential.astFunctionDef, replacementMap) # type: ignore
|
|
337
|
+
# TODO a tool to automatically remove unused variables from the ArgumentsSpecification (return, and returns) _might_ be nice.
|
|
338
|
+
# But, I would need to update the calling function, too.
|
|
339
|
+
ingredientsSequential = decorateCallableWithNumba(ingredientsSequential)
|
|
340
|
+
|
|
341
|
+
ingredientsModuleNumbaUnified = IngredientsModule(
|
|
342
|
+
ingredientsFunction=[ingredientsInitialize,
|
|
343
|
+
ingredientsParallel,
|
|
344
|
+
ingredientsSequential,
|
|
345
|
+
ingredientsDispatcher], imports=LedgerOfImports(numbaFlow.source_astModule))
|
|
346
|
+
|
|
347
|
+
Z0Z_alphaTest_putModuleOnDisk(ingredientsModuleNumbaUnified, numbaFlow)
|
|
348
|
+
|
|
7
349
|
if __name__ == '__main__':
|
|
8
|
-
|
|
9
|
-
dataclassIdentifierAsStr=numbaFlow.dataclassIdentifierAsStr
|
|
10
|
-
, logicalPathModuleDataclass=numbaFlow.logicalPathModuleDataclass
|
|
11
|
-
, dataclassInstanceAsStr=numbaFlow.dataclassInstanceAsStr
|
|
12
|
-
|
|
13
|
-
, dispatcherCallableAsStr=numbaFlow.dispatcherCallableAsStr
|
|
14
|
-
, logicalPathModuleDispatcher=numbaFlow.logicalPathModuleDispatcher
|
|
15
|
-
, dataConverterCallableAsStr=numbaFlow.dataConverterCallableAsStr
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
# initialize with theDao
|
|
19
|
-
dataInitializationHack = "state=makeStateJob(state.mapShape,writeJob=False)"
|
|
20
|
-
ingredientsFunctionDataConverter.FunctionDef.body.insert(0, ast.parse(dataInitializationHack).body[0])
|
|
21
|
-
ingredientsFunctionDataConverter.imports.addImportFromStr('mapFolding.someAssemblyRequired', 'makeStateJob')
|
|
22
|
-
|
|
23
|
-
ingredientsSequential = Z0Z_makeCountingFunction(numbaFlow.sequentialCallableAsStr
|
|
24
|
-
, numbaFlow.sourceAlgorithm
|
|
25
|
-
, inline=True
|
|
26
|
-
, dataclass=False)
|
|
27
|
-
|
|
28
|
-
ingredientsModuleDataConverter = IngredientsModule(
|
|
29
|
-
name=numbaFlow.dataConverterModule,
|
|
30
|
-
ingredientsFunction=ingredientsFunctionDataConverter,
|
|
31
|
-
logicalPathINFIX=numbaFlow.moduleOfSyntheticModules,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
ingredientsModuleDataConverter.writeModule()
|
|
350
|
+
Z0Z_main()
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
from mapFolding.someAssemblyRequired.
|
|
1
|
+
from mapFolding.someAssemblyRequired.transformationTools import (
|
|
2
2
|
ast_Identifier as ast_Identifier,
|
|
3
3
|
extractClassDef as extractClassDef,
|
|
4
4
|
extractFunctionDef as extractFunctionDef,
|
|
5
|
-
executeActionUnlessDescendantMatches as executeActionUnlessDescendantMatches,
|
|
6
5
|
ifThis as ifThis,
|
|
7
6
|
IngredientsFunction as IngredientsFunction,
|
|
8
7
|
IngredientsModule as IngredientsModule,
|
|
9
8
|
LedgerOfImports as LedgerOfImports,
|
|
10
|
-
listNumbaCallableDispatchees as listNumbaCallableDispatchees,
|
|
11
9
|
Make as Make,
|
|
10
|
+
makeDictionaryReplacementStatements as makeDictionaryReplacementStatements,
|
|
12
11
|
NodeCollector as NodeCollector,
|
|
13
12
|
NodeReplacer as NodeReplacer,
|
|
13
|
+
RecipeSynthesizeFlow as RecipeSynthesizeFlow,
|
|
14
14
|
strDotStrCuzPyStoopid as strDotStrCuzPyStoopid,
|
|
15
15
|
Then as Then,
|
|
16
|
+
Z0Z_executeActionUnlessDescendantMatches as Z0Z_executeActionUnlessDescendantMatches,
|
|
16
17
|
)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
1
|
+
from collections.abc import Callable, Sequence
|
|
2
|
+
from mapFolding.someAssemblyRequired import ifThis, IngredientsFunction, Make
|
|
2
3
|
from numba.core.compiler import CompilerBase as numbaCompilerBase
|
|
3
|
-
from typing import Any, TYPE_CHECKING, Final
|
|
4
|
+
from typing import Any, TYPE_CHECKING, Final, cast
|
|
5
|
+
import ast
|
|
4
6
|
|
|
5
7
|
try:
|
|
6
8
|
from typing import NotRequired
|
|
@@ -98,3 +100,86 @@ parametersNumbaMinimum: Final[ParametersNumba] = {
|
|
|
98
100
|
'nopython': False,
|
|
99
101
|
'forceobj': True,
|
|
100
102
|
'parallel': False, }
|
|
103
|
+
|
|
104
|
+
Z0Z_numbaDataTypeModule = 'numba'
|
|
105
|
+
Z0Z_decoratorCallable = 'jit'
|
|
106
|
+
|
|
107
|
+
def thisIsNumbaDotJit(Ima: ast.AST) -> bool:
|
|
108
|
+
return ifThis.isCallNamespace_Identifier(Z0Z_numbaDataTypeModule, Z0Z_decoratorCallable)(Ima)
|
|
109
|
+
|
|
110
|
+
def thisIsJit(Ima: ast.AST) -> bool:
|
|
111
|
+
return ifThis.isCall_Identifier(Z0Z_decoratorCallable)(Ima)
|
|
112
|
+
|
|
113
|
+
def thisIsAnyNumbaJitDecorator(Ima: ast.AST) -> bool:
|
|
114
|
+
return thisIsNumbaDotJit(Ima) or thisIsJit(Ima)
|
|
115
|
+
|
|
116
|
+
def decorateCallableWithNumba(ingredientsFunction: IngredientsFunction, parametersNumba: ParametersNumba | None = None) -> IngredientsFunction:
|
|
117
|
+
def Z0Z_UnhandledDecorators(astCallable: ast.FunctionDef) -> ast.FunctionDef:
|
|
118
|
+
# TODO: more explicit handling of decorators. I'm able to ignore this because I know `algorithmSource` doesn't have any decorators.
|
|
119
|
+
for decoratorItem in astCallable.decorator_list.copy():
|
|
120
|
+
import warnings
|
|
121
|
+
astCallable.decorator_list.remove(decoratorItem)
|
|
122
|
+
warnings.warn(f"Removed decorator {ast.unparse(decoratorItem)} from {astCallable.name}")
|
|
123
|
+
return astCallable
|
|
124
|
+
|
|
125
|
+
def makeSpecialSignatureForNumba(signatureElement: ast.arg) -> ast.Subscript | ast.Name | None:
|
|
126
|
+
if isinstance(signatureElement.annotation, ast.Subscript) and isinstance(signatureElement.annotation.slice, ast.Tuple):
|
|
127
|
+
annotationShape: ast.expr = signatureElement.annotation.slice.elts[0]
|
|
128
|
+
if isinstance(annotationShape, ast.Subscript) and isinstance(annotationShape.slice, ast.Tuple):
|
|
129
|
+
shapeAsListSlices: list[ast.Slice] = [ast.Slice() for _axis in range(len(annotationShape.slice.elts))]
|
|
130
|
+
shapeAsListSlices[-1] = ast.Slice(step=ast.Constant(value=1))
|
|
131
|
+
shapeAST: ast.Slice | ast.Tuple = ast.Tuple(elts=list(shapeAsListSlices), ctx=ast.Load())
|
|
132
|
+
else:
|
|
133
|
+
shapeAST = ast.Slice(step=ast.Constant(value=1))
|
|
134
|
+
|
|
135
|
+
annotationDtype: ast.expr = signatureElement.annotation.slice.elts[1]
|
|
136
|
+
if (isinstance(annotationDtype, ast.Subscript) and isinstance(annotationDtype.slice, ast.Attribute)):
|
|
137
|
+
datatypeAST = annotationDtype.slice.attr
|
|
138
|
+
else:
|
|
139
|
+
datatypeAST = None
|
|
140
|
+
|
|
141
|
+
ndarrayName = signatureElement.arg
|
|
142
|
+
Z0Z_hacky_dtype: str = ndarrayName
|
|
143
|
+
datatype_attr = datatypeAST or Z0Z_hacky_dtype
|
|
144
|
+
ingredientsFunction.imports.addImportFromStr(datatypeModuleDecorator, datatype_attr)
|
|
145
|
+
datatypeNumba = ast.Name(id=datatype_attr, ctx=ast.Load())
|
|
146
|
+
|
|
147
|
+
return ast.Subscript(value=datatypeNumba, slice=shapeAST, ctx=ast.Load())
|
|
148
|
+
|
|
149
|
+
elif isinstance(signatureElement.annotation, ast.Name):
|
|
150
|
+
return signatureElement.annotation
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
datatypeModuleDecorator: str = Z0Z_numbaDataTypeModule
|
|
154
|
+
list_argsDecorator: Sequence[ast.expr] = []
|
|
155
|
+
|
|
156
|
+
list_arg4signature_or_function: list[ast.expr] = []
|
|
157
|
+
for parameter in ingredientsFunction.astFunctionDef.args.args:
|
|
158
|
+
# Efficient translation of Python scalar types to Numba types https://github.com/hunterhogan/mapFolding/issues/8
|
|
159
|
+
# For now, let Numba infer them.
|
|
160
|
+
continue
|
|
161
|
+
signatureElement: ast.Subscript | ast.Name | None = makeSpecialSignatureForNumba(parameter)
|
|
162
|
+
if signatureElement:
|
|
163
|
+
list_arg4signature_or_function.append(signatureElement)
|
|
164
|
+
|
|
165
|
+
if ingredientsFunction.astFunctionDef.returns and isinstance(ingredientsFunction.astFunctionDef.returns, ast.Name):
|
|
166
|
+
theReturn: ast.Name = ingredientsFunction.astFunctionDef.returns
|
|
167
|
+
list_argsDecorator = [cast(ast.expr, ast.Call(func=ast.Name(id=theReturn.id, ctx=ast.Load())
|
|
168
|
+
, args=list_arg4signature_or_function if list_arg4signature_or_function else [], keywords=[] ) )]
|
|
169
|
+
elif list_arg4signature_or_function:
|
|
170
|
+
list_argsDecorator = [cast(ast.expr, ast.Tuple(elts=list_arg4signature_or_function, ctx=ast.Load()))]
|
|
171
|
+
|
|
172
|
+
ingredientsFunction.astFunctionDef = Z0Z_UnhandledDecorators(ingredientsFunction.astFunctionDef)
|
|
173
|
+
if parametersNumba is None:
|
|
174
|
+
parametersNumba = parametersNumbaDEFAULT
|
|
175
|
+
listDecoratorKeywords: list[ast.keyword] = [Make.ast_keyword(parameterName, Make.astConstant(parameterValue)) for parameterName, parameterValue in parametersNumba.items()]
|
|
176
|
+
|
|
177
|
+
decoratorModule: str = Z0Z_numbaDataTypeModule
|
|
178
|
+
decoratorCallable: str = Z0Z_decoratorCallable
|
|
179
|
+
ingredientsFunction.imports.addImportFromStr(decoratorModule, decoratorCallable)
|
|
180
|
+
# Leave this line in so that global edits will change it.
|
|
181
|
+
astDecorator: ast.Call = Make.astCall(Make.astName(decoratorCallable), list_argsDecorator, listDecoratorKeywords)
|
|
182
|
+
astDecorator: ast.Call = Make.astCall(Make.astName(decoratorCallable), list_astKeywords=listDecoratorKeywords) # type: ignore[no-redef]
|
|
183
|
+
|
|
184
|
+
ingredientsFunction.astFunctionDef.decorator_list = [astDecorator]
|
|
185
|
+
return ingredientsFunction
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
from collections.abc import Sequence
|
|
2
2
|
from importlib import import_module
|
|
3
3
|
from inspect import getsource as inspect_getsource
|
|
4
|
-
from
|
|
5
|
-
from types import ModuleType
|
|
6
|
-
from typing import Any, cast, overload, Literal
|
|
7
|
-
import ast
|
|
8
|
-
import pickle
|
|
9
|
-
from mapFolding.beDRY import ComputationState, outfitCountFolds, validateListDimensions
|
|
4
|
+
from mapFolding.beDRY import outfitCountFolds, validateListDimensions
|
|
10
5
|
from mapFolding.filesystem import getPathFilenameFoldsTotal
|
|
11
6
|
from mapFolding.someAssemblyRequired import (
|
|
12
7
|
ast_Identifier,
|
|
13
|
-
executeActionUnlessDescendantMatches,
|
|
14
8
|
extractClassDef,
|
|
15
9
|
ifThis,
|
|
16
|
-
IngredientsFunction,
|
|
17
10
|
LedgerOfImports,
|
|
18
11
|
Make,
|
|
19
12
|
NodeCollector,
|
|
20
13
|
strDotStrCuzPyStoopid,
|
|
21
14
|
Then,
|
|
15
|
+
Z0Z_executeActionUnlessDescendantMatches,
|
|
22
16
|
)
|
|
23
|
-
from mapFolding.theSSOT import getSourceAlgorithm
|
|
17
|
+
from mapFolding.theSSOT import ComputationState, getSourceAlgorithm
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from types import ModuleType
|
|
20
|
+
from typing import Any, Literal, overload
|
|
21
|
+
import ast
|
|
22
|
+
import pickle
|
|
23
|
+
|
|
24
|
+
# Would `LibCST` be better than `ast` in some cases? https://github.com/hunterhogan/mapFolding/issues/7
|
|
24
25
|
|
|
25
26
|
def shatter_dataclassesDOTdataclass(logicalPathModule: strDotStrCuzPyStoopid, dataclass_Identifier: ast_Identifier, instance_Identifier: ast_Identifier
|
|
26
|
-
|
|
27
|
+
)-> tuple[ast.Name, LedgerOfImports, list[ast.AnnAssign], ast.Tuple, list[ast.Name], list[ast.arg], ast.Subscript, ast.Assign, list[ast.keyword]]:
|
|
27
28
|
"""
|
|
28
29
|
Parameters:
|
|
29
30
|
logicalPathModule: gimme string cuz python is stoopid
|
|
@@ -37,63 +38,44 @@ def shatter_dataclassesDOTdataclass(logicalPathModule: strDotStrCuzPyStoopid, da
|
|
|
37
38
|
if not isinstance(dataclass, ast.ClassDef):
|
|
38
39
|
raise ValueError(f"I could not find {dataclass_Identifier=} in {logicalPathModule=}.")
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
ledgerDataclassANDFragments = LedgerOfImports()
|
|
42
|
+
list_ast_argAnnotated4ArgumentsSpecification: list[ast.arg] = []
|
|
43
|
+
list_keyword4DataclassInitialization: list[ast.keyword] = []
|
|
44
|
+
listAnnAssign4DataclassUnpack: list[ast.AnnAssign] = []
|
|
45
|
+
listAnnotations: list[ast.expr] = []
|
|
46
|
+
listNameDataclassFragments4Parameters: list[ast.Name] = []
|
|
44
47
|
|
|
45
48
|
addToLedgerPredicate = ifThis.isAnnAssignAndAnnotationIsName
|
|
46
|
-
addToLedgerAction = Then.Z0Z_ledger(logicalPathModule,
|
|
49
|
+
addToLedgerAction = Then.Z0Z_ledger(logicalPathModule, ledgerDataclassANDFragments)
|
|
47
50
|
addToLedger = NodeCollector(addToLedgerPredicate, [addToLedgerAction])
|
|
48
51
|
|
|
49
52
|
exclusionPredicate = ifThis.is_keyword_IdentifierEqualsConstantValue('init', False)
|
|
50
|
-
appendKeywordAction = Then.Z0Z_appendKeywordMirroredTo(
|
|
51
|
-
filteredAppendKeywordAction =
|
|
53
|
+
appendKeywordAction = Then.Z0Z_appendKeywordMirroredTo(list_keyword4DataclassInitialization)
|
|
54
|
+
filteredAppendKeywordAction = Z0Z_executeActionUnlessDescendantMatches(exclusionPredicate, appendKeywordAction) # type: ignore
|
|
52
55
|
|
|
53
56
|
collector = NodeCollector(
|
|
54
57
|
ifThis.isAnnAssignAndTargetIsName,
|
|
55
|
-
[Then.
|
|
56
|
-
, Then.append_targetTo(
|
|
58
|
+
[Then.Z0Z_appendAnnAssignOf_nameDOTnameTo(instance_Identifier, listAnnAssign4DataclassUnpack)
|
|
59
|
+
, Then.append_targetTo(listNameDataclassFragments4Parameters) # type: ignore
|
|
57
60
|
, lambda node: addToLedger.visit(node)
|
|
58
61
|
, filteredAppendKeywordAction
|
|
62
|
+
, lambda node: list_ast_argAnnotated4ArgumentsSpecification.append(Make.ast_arg(node.target.id, node.annotation)) # type: ignore
|
|
63
|
+
, lambda node: listAnnotations.append(node.annotation) # type: ignore
|
|
59
64
|
]
|
|
60
65
|
)
|
|
61
66
|
|
|
62
67
|
collector.visit(dataclass)
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
astNameDataclass = Make.astName(dataclass_Identifier)
|
|
67
|
-
astTupleForAssignTargetsToFragments: ast.Tuple = Make.astTuple(list_astNameDataclassFragments, ast.Store())
|
|
68
|
-
return astNameDataclass, ledgerDataclassAndFragments, list_astAnnAssign, list_astNameDataclassFragments, listKeywordForDataclassInitialization, astTupleForAssignTargetsToFragments
|
|
69
|
-
|
|
70
|
-
def makeDataclassConverter(dataclassIdentifierAsStr: str,
|
|
71
|
-
logicalPathModuleDataclass: str,
|
|
72
|
-
dataclassInstanceAsStr: str,
|
|
73
|
-
dispatcherCallableAsStr: str,
|
|
74
|
-
logicalPathModuleDispatcher: str,
|
|
75
|
-
dataConverterCallableAsStr: str,
|
|
76
|
-
) -> IngredientsFunction:
|
|
77
|
-
|
|
78
|
-
astNameDataclass, ledgerDataclassAndFragments, list_astAnnAssign, list_astNameDataclassFragments, list_astKeywordDataclassFragments, astTupleForAssignTargetsToFragments = shatter_dataclassesDOTdataclass(logicalPathModuleDataclass, dataclassIdentifierAsStr, dataclassInstanceAsStr)
|
|
79
|
-
|
|
80
|
-
ingredientsFunction = IngredientsFunction(
|
|
81
|
-
FunctionDef = Make.astFunctionDef(name=dataConverterCallableAsStr
|
|
82
|
-
, argumentsSpecification=Make.astArgumentsSpecification(args=[Make.astArg(dataclassInstanceAsStr, astNameDataclass)])
|
|
83
|
-
, body = cast(list[ast.stmt], list_astAnnAssign)
|
|
84
|
-
, returns = astNameDataclass
|
|
85
|
-
)
|
|
86
|
-
, imports = ledgerDataclassAndFragments
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
callToDispatcher = Make.astAssign(listTargets=[astTupleForAssignTargetsToFragments]
|
|
90
|
-
, value=Make.astCall(Make.astName(dispatcherCallableAsStr), args=list_astNameDataclassFragments))
|
|
91
|
-
ingredientsFunction.FunctionDef.body.append(callToDispatcher)
|
|
92
|
-
ingredientsFunction.imports.addImportFromStr(logicalPathModuleDispatcher, dispatcherCallableAsStr)
|
|
69
|
+
astSubscriptPrimitiveTupleAnnotations4FunctionDef_returns = Make.astSubscript(Make.astName('tuple'), Make.astTuple(listAnnotations))
|
|
93
70
|
|
|
94
|
-
|
|
71
|
+
ledgerDataclassANDFragments.addImportFromStr(logicalPathModule, dataclass_Identifier)
|
|
95
72
|
|
|
96
|
-
|
|
73
|
+
astName_dataclassesDOTdataclass = Make.astName(dataclass_Identifier)
|
|
74
|
+
astTuple4AssignTargetsToFragments: ast.Tuple = Make.astTuple(listNameDataclassFragments4Parameters, ast.Store())
|
|
75
|
+
astAssignDataclassRepack = Make.astAssign(listTargets=[Make.astName(instance_Identifier)], value=Make.astCall(astName_dataclassesDOTdataclass, list_astKeywords=list_keyword4DataclassInitialization))
|
|
76
|
+
return (astName_dataclassesDOTdataclass, ledgerDataclassANDFragments, listAnnAssign4DataclassUnpack,
|
|
77
|
+
astTuple4AssignTargetsToFragments, listNameDataclassFragments4Parameters, list_ast_argAnnotated4ArgumentsSpecification,
|
|
78
|
+
astSubscriptPrimitiveTupleAnnotations4FunctionDef_returns, astAssignDataclassRepack, list_keyword4DataclassInitialization)
|
|
97
79
|
|
|
98
80
|
@overload
|
|
99
81
|
def makeStateJob(listDimensions: Sequence[int], *, writeJob: Literal[True], **keywordArguments: Any) -> Path: ...
|
|
@@ -116,11 +98,11 @@ def makeStateJob(listDimensions: Sequence[int], *, writeJob: bool = True, **keyw
|
|
|
116
98
|
the path to the saved state file if writeJob is True.
|
|
117
99
|
"""
|
|
118
100
|
mapShape = validateListDimensions(listDimensions)
|
|
119
|
-
stateUniversal = outfitCountFolds(mapShape, **keywordArguments)
|
|
101
|
+
stateUniversal: ComputationState = outfitCountFolds(mapShape, **keywordArguments)
|
|
120
102
|
|
|
121
103
|
moduleSource: ModuleType = getSourceAlgorithm()
|
|
122
104
|
# TODO `countInitialize` is hardcoded
|
|
123
|
-
stateUniversal
|
|
105
|
+
stateUniversal = moduleSource.countInitialize(stateUniversal)
|
|
124
106
|
|
|
125
107
|
if not writeJob:
|
|
126
108
|
return stateUniversal
|