mapFolding 0.9.3__py3-none-any.whl → 0.9.5__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.
Files changed (36) hide show
  1. mapFolding/__init__.py +41 -7
  2. mapFolding/basecamp.py +100 -9
  3. mapFolding/beDRY.py +7 -15
  4. mapFolding/dataBaskets.py +12 -0
  5. mapFolding/datatypes.py +4 -4
  6. mapFolding/oeis.py +2 -7
  7. mapFolding/someAssemblyRequired/RecipeJob.py +97 -3
  8. mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +326 -0
  9. mapFolding/someAssemblyRequired/__init__.py +37 -29
  10. mapFolding/someAssemblyRequired/_theTypes.py +19 -19
  11. mapFolding/someAssemblyRequired/_tool_Make.py +12 -6
  12. mapFolding/someAssemblyRequired/_tool_Then.py +59 -21
  13. mapFolding/someAssemblyRequired/_toolboxAST.py +57 -0
  14. mapFolding/someAssemblyRequired/_toolboxAntecedents.py +123 -40
  15. mapFolding/someAssemblyRequired/_toolboxContainers.py +128 -37
  16. mapFolding/someAssemblyRequired/_toolboxPython.py +52 -50
  17. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +274 -0
  18. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +6 -4
  19. mapFolding/someAssemblyRequired/toolboxNumba.py +3 -27
  20. mapFolding/someAssemblyRequired/transformationTools.py +47 -177
  21. mapFolding/syntheticModules/daoOfMapFolding.py +74 -0
  22. mapFolding/syntheticModules/dataPacking.py +25 -0
  23. mapFolding/syntheticModules/initializeCount.py +49 -0
  24. mapFolding/syntheticModules/theorem2.py +49 -0
  25. mapFolding/syntheticModules/theorem2Numba.py +45 -0
  26. mapFolding/syntheticModules/theorem2Trimmed.py +43 -0
  27. {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/METADATA +2 -1
  28. mapfolding-0.9.5.dist-info/RECORD +59 -0
  29. {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/WHEEL +1 -1
  30. tests/test_computations.py +4 -2
  31. mapFolding/Z0Z_flowControl.py +0 -99
  32. mapfolding-0.9.3.dist-info/RECORD +0 -51
  33. /mapFolding/{theDaoOfMapFolding.py → daoOfMapFolding.py} +0 -0
  34. {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/entry_points.txt +0 -0
  35. {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/licenses/LICENSE +0 -0
  36. {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,15 @@
1
1
  """
2
2
  AST Node Transformation Actions for Python Code Manipulation
3
3
 
4
- This module provides the Then class with static methods for generating callable
5
- action functions that specify what to do with AST nodes that match predicates.
6
- These action functions are used primarily with NodeChanger and NodeTourist to
4
+ This module provides the Then class with static methods for generating callable action functions that specify what to do
5
+ with AST nodes that match predicates. These action functions are used primarily with NodeChanger and NodeTourist to
7
6
  transform or extract information from AST nodes.
8
7
 
9
- The module also contains the grab class that provides functions for modifying
10
- specific attributes of AST nodes while preserving their structure, enabling
11
- fine-grained control when transforming AST structures.
8
+ The module also contains the grab class that provides functions for modifying specific attributes of AST nodes while
9
+ preserving their structure, enabling fine-grained control when transforming AST structures.
12
10
 
13
- Together, these classes provide a complete system for manipulating AST nodes
14
- once they have been identified using predicate functions from ifThis.
11
+ Together, these classes provide a complete system for manipulating AST nodes once they have been identified using
12
+ predicate functions from ifThis.
15
13
  """
16
14
 
17
15
  from collections.abc import Callable, Sequence
@@ -23,15 +21,21 @@ class grab:
23
21
  """
24
22
  Modify specific attributes of AST nodes while preserving the node structure.
25
23
 
26
- The grab class provides static methods that create transformation functions to modify
27
- specific attributes of AST nodes. Unlike DOT which provides read-only access,
28
- grab allows for targeted modifications of node attributes without replacing the
29
- entire node.
24
+ The grab class provides static methods that create transformation functions to modify specific attributes of AST
25
+ nodes. Unlike DOT which provides read-only access, grab allows for targeted modifications of node attributes without
26
+ replacing the entire node.
30
27
 
31
- Each method returns a function that takes a node, applies a transformation to a
32
- specific attribute of that node, and returns the modified node. This enables fine-grained
33
- control when transforming AST structures.
28
+ Each method returns a function that takes a node, applies a transformation to a specific attribute of that node, and
29
+ returns the modified node. This enables fine-grained control when transforming AST structures.
34
30
  """
31
+ @staticmethod
32
+ def andDoAllOf(listOfActions: list[Callable[[NodeORattribute], NodeORattribute]]) -> Callable[[NodeORattribute], NodeORattribute]:
33
+ def workhorse(node: NodeORattribute) -> NodeORattribute:
34
+ for action in listOfActions:
35
+ node = action(node)
36
+ return node
37
+ return workhorse
38
+
35
39
  @staticmethod
36
40
  def argAttribute(action: Callable[[ast_Identifier | None], ast_Identifier]) -> Callable[[ast.arg | ast.keyword], ast.arg | ast.keyword]:
37
41
  def workhorse(node: ast.arg | ast.keyword) -> ast.arg | ast.keyword:
@@ -39,6 +43,20 @@ class grab:
39
43
  return node
40
44
  return workhorse
41
45
 
46
+ @staticmethod
47
+ def attrAttribute(action: Callable[[ast_Identifier], ast_Identifier]) -> Callable[[ast.Attribute], ast.Attribute]:
48
+ def workhorse(node: ast.Attribute) -> ast.Attribute:
49
+ node.attr = action(node.attr)
50
+ return node
51
+ return workhorse
52
+
53
+ @staticmethod
54
+ def comparatorsAttribute(action: Callable[[list[ast.expr]], list[ast.expr]]) -> Callable[[ast.Compare], ast.Compare]:
55
+ def workhorse(node: ast.Compare) -> ast.Compare:
56
+ node.comparators = action(node.comparators)
57
+ return node
58
+ return workhorse
59
+
42
60
  @staticmethod
43
61
  def funcAttribute(action: Callable[[ast.expr], ast.expr]) -> Callable[[ast.Call], ast.Call]:
44
62
  def workhorse(node: ast.Call) -> ast.Call:
@@ -60,6 +78,27 @@ class grab:
60
78
  return node
61
79
  return workhorse
62
80
 
81
+ @staticmethod
82
+ def leftAttribute(action: Callable[[ast.expr], ast.expr]) -> Callable[[ast.BinOp | ast.Compare], ast.BinOp | ast.Compare]:
83
+ def workhorse(node: ast.BinOp | ast.Compare) -> ast.BinOp | ast.Compare:
84
+ node.left = action(node.left)
85
+ return node
86
+ return workhorse
87
+
88
+ @staticmethod
89
+ def opsAttribute(action: Callable[[list[ast.cmpop]], list[ast.cmpop]]) -> Callable[[ast.Compare], ast.Compare]:
90
+ def workhorse(node: ast.Compare) -> ast.Compare:
91
+ node.ops = action(node.ops)
92
+ return node
93
+ return workhorse
94
+
95
+ @staticmethod
96
+ def testAttribute(action: Callable[[ast.expr], ast.expr]) -> Callable[[ast.Assert | ast.If | ast.IfExp | ast.While], ast.Assert | ast.If | ast.IfExp | ast.While]:
97
+ def workhorse(node: ast.Assert | ast.If | ast.IfExp | ast.While) -> ast.Assert | ast.If | ast.IfExp | ast.While:
98
+ node.test = action(node.test)
99
+ return node
100
+ return workhorse
101
+
63
102
  @staticmethod
64
103
  def valueAttribute(action: Callable[[Any], Any]) -> Callable[[astClassHasDOTvalue], astClassHasDOTvalue]:
65
104
  def workhorse(node: astClassHasDOTvalue) -> astClassHasDOTvalue:
@@ -71,13 +110,12 @@ class Then:
71
110
  """
72
111
  Provide action functions that specify what to do with AST nodes that match predicates.
73
112
 
74
- The Then class contains static methods that generate action functions used with
75
- NodeChanger and NodeTourist to transform or extract information from AST nodes
76
- that match specific predicates. These actions include node replacement, insertion,
77
- extraction, and collection operations.
113
+ The Then class contains static methods that generate action functions used with NodeChanger and NodeTourist to
114
+ transform or extract information from AST nodes that match specific predicates. These actions include node
115
+ replacement, insertion, extraction, and collection operations.
78
116
 
79
- When paired with predicates from the ifThis class, Then methods complete the
80
- pattern-matching-and-action workflow for AST manipulation.
117
+ When paired with predicates from the ifThis class, Then methods complete the pattern-matching-and-action workflow
118
+ for AST manipulation.
81
119
  """
82
120
  @staticmethod
83
121
  def appendTo(listOfAny: list[Any]) -> Callable[[ast.AST | ast_Identifier], ast.AST | ast_Identifier]:
@@ -0,0 +1,57 @@
1
+ from mapFolding.someAssemblyRequired import ast_Identifier, ifThis, IngredientsFunction, LedgerOfImports, NodeTourist, Then
2
+ from mapFolding.theSSOT import raiseIfNoneGitHubIssueNumber3
3
+ import ast
4
+
5
+ def astModuleToIngredientsFunction(astModule: ast.AST, identifierFunctionDef: ast_Identifier) -> IngredientsFunction:
6
+ """
7
+ Extract a function definition from an AST module and create an `IngredientsFunction`.
8
+
9
+ This function finds a function definition with the specified identifier in the given AST module, extracts it, and
10
+ stores all module imports in the `LedgerOfImports`.
11
+
12
+ Parameters:
13
+ astModule: The AST module containing the function definition.
14
+ identifierFunctionDef: The name of the function to extract.
15
+
16
+ Returns:
17
+ ingredientsFunction: `IngredientsFunction` object containing the `ast.FunctionDef` and _all_ imports from the
18
+ source module.
19
+
20
+ Raises:
21
+ raiseIfNoneGitHubIssueNumber3: If the function definition is not found.
22
+ """
23
+ astFunctionDef = extractFunctionDef(astModule, identifierFunctionDef)
24
+ if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
25
+ return IngredientsFunction(astFunctionDef, LedgerOfImports(astModule))
26
+
27
+ def extractClassDef(module: ast.AST, identifier: ast_Identifier) -> ast.ClassDef | None:
28
+ """
29
+ Extract a class definition with a specific name from an AST module.
30
+
31
+ This function searches through an AST module for a class definition that matches the provided identifier and returns
32
+ it if found.
33
+
34
+ Parameters:
35
+ module: The AST module to search within.
36
+ identifier: The name of the class to find.
37
+
38
+ Returns:
39
+ astClassDef|None: The matching class definition AST node, or `None` if not found.
40
+ """
41
+ return NodeTourist(ifThis.isClassDef_Identifier(identifier), Then.extractIt).captureLastMatch(module)
42
+
43
+ def extractFunctionDef(module: ast.AST, identifier: ast_Identifier) -> ast.FunctionDef | None:
44
+ """
45
+ Extract a function definition with a specific name from an AST module.
46
+
47
+ This function searches through an AST module for a function definition that matches the provided identifier and
48
+ returns it if found.
49
+
50
+ Parameters:
51
+ module: The AST module to search within.
52
+ identifier: The name of the function to find.
53
+
54
+ Returns:
55
+ astFunctionDef|None: The matching function definition AST node, or `None` if not found.
56
+ """
57
+ return NodeTourist(ifThis.isFunctionDef_Identifier(identifier), Then.extractIt).captureLastMatch(module)
@@ -1,35 +1,38 @@
1
1
  """
2
2
  AST Node Predicate and Access Utilities for Pattern Matching and Traversal
3
3
 
4
- This module provides utilities for accessing and matching AST nodes in a consistent way.
5
- It contains three primary classes:
4
+ This module provides utilities for accessing and matching AST nodes in a consistent way. It contains three primary
5
+ classes:
6
6
 
7
- 1. DOT: Provides consistent accessor methods for AST node attributes across different
8
- node types, simplifying the access to node properties.
7
+ 1. DOT: Provides consistent accessor methods for AST node attributes across different node types, simplifying the access
8
+ to node properties.
9
9
 
10
- 2. be: Offers type-guard functions that verify AST node types, enabling safe type
11
- narrowing for static type checking and improving code safety.
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
12
 
13
- 3. ifThis: Contains predicate functions for matching AST nodes based on various criteria,
14
- enabling precise targeting of nodes for analysis or transformation.
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
15
 
16
- These utilities form the foundation of the pattern-matching component in the AST
17
- manipulation framework, working in conjunction with the NodeChanger and NodeTourist
18
- classes to enable precise and targeted code transformations. Together, they implement
19
- a declarative approach to AST manipulation that separates node identification (ifThis),
20
- type verification (be), and data access (DOT).
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).
21
20
  """
22
21
 
23
22
  from collections.abc import Callable
24
23
  from mapFolding.someAssemblyRequired import (
25
24
  ast_Identifier,
25
+ astClassHasDOTbody,
26
+ astClassHasDOTbody_expr,
27
+ astClassHasDOTbodyList_stmt,
26
28
  astClassHasDOTnameNotName,
29
+ astClassHasDOTnameNotNameAlways,
30
+ astClassHasDOTnameNotNameOptionally,
27
31
  astClassHasDOTtarget,
28
- astClassHasDOTtargetAttributeNameSubscript,
29
32
  astClassHasDOTtarget_expr,
33
+ astClassHasDOTtargetAttributeNameSubscript,
30
34
  astClassHasDOTvalue,
31
35
  astClassHasDOTvalue_expr,
32
- astClassOptionallyHasDOTnameNotName,
33
36
  astClassHasDOTvalue_exprNone,
34
37
  ImaCallToName,
35
38
  )
@@ -40,13 +43,12 @@ class DOT:
40
43
  """
41
44
  Access attributes and sub-nodes of AST elements via consistent accessor methods.
42
45
 
43
- The DOT class provides static methods to access specific attributes of different
44
- types of AST nodes in a consistent way. This simplifies attribute access across
45
- various node types and improves code readability by abstracting the underlying
46
- AST structure details.
46
+ The DOT class provides static methods to access specific attributes of different types of AST nodes in a consistent
47
+ way. This simplifies attribute access across various node types and improves code readability by abstracting the
48
+ underlying AST structure details.
47
49
 
48
- DOT is designed for safe, read-only access to node properties, unlike the grab
49
- class which is designed for modifying node attributes.
50
+ DOT is designed for safe, read-only access to node properties, unlike the grab class which is designed for modifying
51
+ node attributes.
50
52
  """
51
53
  @staticmethod
52
54
  @overload
@@ -72,6 +74,16 @@ class DOT:
72
74
  def attr(node: ast.Attribute) -> ast_Identifier:
73
75
  return node.attr
74
76
 
77
+ @staticmethod
78
+ @overload
79
+ def body(node: astClassHasDOTbodyList_stmt) -> list[ast.stmt]:...
80
+ @staticmethod
81
+ @overload
82
+ def body(node: astClassHasDOTbody_expr) -> ast.expr:...
83
+ @staticmethod
84
+ def body(node: astClassHasDOTbody) -> ast.expr | list[ast.stmt]:
85
+ return node.body
86
+
75
87
  @staticmethod
76
88
  @overload
77
89
  def func(node: ImaCallToName) -> ast.Name:...
@@ -88,12 +100,12 @@ class DOT:
88
100
 
89
101
  @staticmethod
90
102
  @overload
91
- def name(node: astClassHasDOTnameNotName) -> ast_Identifier:...
103
+ def name(node: astClassHasDOTnameNotNameAlways) -> ast_Identifier:...
92
104
  @staticmethod
93
105
  @overload
94
- def name(node: astClassOptionallyHasDOTnameNotName) -> ast_Identifier | None:...
106
+ def name(node: astClassHasDOTnameNotNameOptionally) -> ast_Identifier | None:...
95
107
  @staticmethod
96
- def name(node: astClassHasDOTnameNotName | astClassOptionallyHasDOTnameNotName) -> ast_Identifier | None:
108
+ def name(node: astClassHasDOTnameNotName) -> ast_Identifier | None:
97
109
  return node.name
98
110
 
99
111
  @staticmethod
@@ -129,18 +141,16 @@ class be:
129
141
  """
130
142
  Provide type-guard functions for safely verifying AST node types during manipulation.
131
143
 
132
- The be class contains static methods that perform runtime type verification of AST nodes,
133
- returning TypeGuard results that enable static type checkers to narrow node types in
134
- conditional branches. These type-guards:
144
+ The be class contains static methods that perform runtime type verification of AST nodes, returning TypeGuard
145
+ results that enable static type checkers to narrow node types in conditional branches. These type-guards:
135
146
 
136
- 1. Improve code safety by preventing operations on incompatible node types
137
- 2. Enable IDE tooling to provide better autocompletion and error detection
138
- 3. Document expected node types in a way that's enforced by the type system
139
- 4. Support pattern-matching workflows where node types must be verified before access
147
+ 1. Improve code safety by preventing operations on incompatible node types.
148
+ 2. Enable IDE tooling to provide better autocompletion and error detection.
149
+ 3. Document expected node types in a way that's enforced by the type system.
150
+ 4. Support pattern-matching workflows where node types must be verified before access.
140
151
 
141
- When used with conditional statements, these type-guards allow for precise,
142
- type-safe manipulation of AST nodes while maintaining full static type checking
143
- capabilities, even in complex transformation scenarios.
152
+ When used with conditional statements, these type-guards allow for precise, type-safe manipulation of AST nodes
153
+ while maintaining full static type checking capabilities, even in complex transformation scenarios.
144
154
  """
145
155
  @staticmethod
146
156
  def AnnAssign(node: ast.AST) -> TypeGuard[ast.AnnAssign]:
@@ -170,6 +180,14 @@ class be:
170
180
  def ClassDef(node: ast.AST) -> TypeGuard[ast.ClassDef]:
171
181
  return isinstance(node, ast.ClassDef)
172
182
 
183
+ @staticmethod
184
+ def Compare(node: ast.AST) -> TypeGuard[ast.Compare]:
185
+ return isinstance(node, ast.Compare)
186
+
187
+ @staticmethod
188
+ def Constant(node: ast.AST) -> TypeGuard[ast.Constant]:
189
+ return isinstance(node, ast.Constant)
190
+
173
191
  @staticmethod
174
192
  def FunctionDef(node: ast.AST) -> TypeGuard[ast.FunctionDef]:
175
193
  return isinstance(node, ast.FunctionDef)
@@ -178,10 +196,26 @@ class be:
178
196
  def keyword(node: ast.AST) -> TypeGuard[ast.keyword]:
179
197
  return isinstance(node, ast.keyword)
180
198
 
199
+ @staticmethod
200
+ def If(node: ast.AST) -> TypeGuard[ast.If]:
201
+ return isinstance(node, ast.If)
202
+
203
+ @staticmethod
204
+ def Gt(node: ast.AST) -> TypeGuard[ast.Gt]:
205
+ return isinstance(node, ast.Gt)
206
+
207
+ @staticmethod
208
+ def LtE(node: ast.AST) -> TypeGuard[ast.LtE]:
209
+ return isinstance(node, ast.LtE)
210
+
181
211
  @staticmethod
182
212
  def Name(node: ast.AST) -> TypeGuard[ast.Name]:
183
213
  return isinstance(node, ast.Name)
184
214
 
215
+ @staticmethod
216
+ def Not(node: ast.AST) -> TypeGuard[ast.Not]:
217
+ return isinstance(node, ast.Not)
218
+
185
219
  @staticmethod
186
220
  def Return(node: ast.AST) -> TypeGuard[ast.Return]:
187
221
  return isinstance(node, ast.Return)
@@ -194,17 +228,28 @@ class be:
194
228
  def Subscript(node: ast.AST) -> TypeGuard[ast.Subscript]:
195
229
  return isinstance(node, ast.Subscript)
196
230
 
231
+ @staticmethod
232
+ def Tuple(node: ast.AST) -> TypeGuard[ast.Tuple]:
233
+ return isinstance(node, ast.Tuple)
234
+
235
+ @staticmethod
236
+ def UnaryOp(node: ast.AST) -> TypeGuard[ast.UnaryOp]:
237
+ return isinstance(node, ast.UnaryOp)
238
+
239
+ @staticmethod
240
+ def While(node: ast.AST) -> TypeGuard[ast.While]:
241
+ return isinstance(node, ast.While)
242
+
197
243
  class ifThis:
198
244
  """
199
245
  Provide predicate functions for matching and filtering AST nodes based on various criteria.
200
246
 
201
- The ifThis class contains static methods that generate predicate functions used to test
202
- whether AST nodes match specific criteria. These predicates can be used with NodeChanger
203
- and NodeTourist to identify and process specific patterns in the AST.
247
+ The ifThis class contains static methods that generate predicate functions used to test whether AST nodes match
248
+ specific criteria. These predicates can be used with NodeChanger and NodeTourist to identify and process specific
249
+ patterns in the AST.
204
250
 
205
- The class provides predicates for matching various node types, attributes, identifiers,
206
- and structural patterns, enabling precise targeting of AST elements for analysis or
207
- transformation.
251
+ The class provides predicates for matching various node types, attributes, identifiers, and structural patterns,
252
+ enabling precise targeting of AST elements for analysis or transformation.
208
253
  """
209
254
  @staticmethod
210
255
  def _Identifier(identifier: ast_Identifier) -> Callable[[ast_Identifier | None], TypeGuard[ast_Identifier] | bool]:
@@ -257,6 +302,40 @@ class ifThis:
257
302
  def isAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
258
303
  return lambda node: ifThis.isAttributeName(node) and ifThis.isName_Identifier(namespace)(DOT.value(node)) and ifThis._Identifier(identifier)(DOT.attr(node))
259
304
 
305
+ @staticmethod
306
+ def isAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
307
+ return lambda node: (be.Compare(node)
308
+ and ifThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
309
+ and be.Gt(node.ops[0])
310
+ and ifThis.isConstant_value(0)(node.comparators[0]))
311
+
312
+ @staticmethod
313
+ def isUnaryNotAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.UnaryOp] | bool]:
314
+ return lambda node: (be.UnaryOp(node)
315
+ and be.Not(node.op)
316
+ and ifThis.isAttributeNamespace_Identifier(namespace, identifier)(node.operand))
317
+
318
+ @staticmethod
319
+ def isIfUnaryNotAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.If] | bool]:
320
+ return lambda node: (be.If(node)
321
+ and ifThis.isUnaryNotAttributeNamespace_Identifier(namespace, identifier)(node.test))
322
+
323
+ @staticmethod
324
+ def isIfAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.If] | bool]:
325
+ return lambda node: (be.If(node)
326
+ and ifThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
327
+
328
+ @staticmethod
329
+ def isWhileAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.While] | bool]:
330
+ return lambda node: (be.While(node)
331
+ and ifThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
332
+
333
+ @staticmethod
334
+ def isAttributeNamespace_IdentifierLessThanOrEqual(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
335
+ return lambda node: (be.Compare(node)
336
+ and ifThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
337
+ and be.LtE(node.ops[0]))
338
+
260
339
  @staticmethod
261
340
  def isAugAssign_targetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AugAssign] | bool]:
262
341
  def workhorse(node: ast.AST) -> TypeGuard[ast.AugAssign] | bool:
@@ -282,6 +361,10 @@ class ifThis:
282
361
  def isClassDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.ClassDef] | bool]:
283
362
  return lambda node: be.ClassDef(node) and ifThis._Identifier(identifier)(DOT.name(node))
284
363
 
364
+ @staticmethod
365
+ def isConstant_value(value: Any) -> Callable[[ast.AST], TypeGuard[ast.Constant] | bool]:
366
+ return lambda node: be.Constant(node) and DOT.value(node) == value
367
+
285
368
  @staticmethod
286
369
  def isFunctionDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.FunctionDef] | bool]:
287
370
  return lambda node: be.FunctionDef(node) and ifThis._Identifier(identifier)(DOT.name(node))
@@ -19,9 +19,11 @@ specific optimizations and transformations.
19
19
  """
20
20
 
21
21
  from collections import defaultdict
22
- from collections.abc import Sequence
23
- from mapFolding.someAssemblyRequired import ast_Identifier, Make, parseLogicalPath2astModule, str_nameDOTname
24
- from mapFolding.theSSOT import The
22
+ from collections.abc import Callable, Sequence
23
+ from copy import deepcopy
24
+ from typing import Any
25
+ from mapFolding.someAssemblyRequired import ast_Identifier, DOT, ifThis, Make, NodeTourist, parseLogicalPath2astModule, str_nameDOTname, Then
26
+ from mapFolding.theSSOT import raiseIfNoneGitHubIssueNumber3, The
25
27
  from pathlib import Path, PurePosixPath
26
28
  from Z0Z_tools import updateExtendPolishDictionaryLists
27
29
  import ast
@@ -32,8 +34,7 @@ class LedgerOfImports:
32
34
  Track and manage import statements for programmatically generated code.
33
35
 
34
36
  LedgerOfImports acts as a registry for import statements, maintaining a clean separation between the logical
35
- structure of imports and their textual representation.
36
- It enables:
37
+ structure of imports and their textual representation. It enables:
37
38
 
38
39
  1. Tracking regular imports and import-from statements.
39
40
  2. Adding imports programmatically during code transformation.
@@ -46,8 +47,6 @@ class LedgerOfImports:
46
47
  """
47
48
  # TODO When resolving the ledger of imports, remove self-referential imports
48
49
 
49
- type_ignores: list[ast.TypeIgnore]
50
-
51
50
  def __init__(self, startWith: ast.AST | None = None, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
52
51
  self.dictionaryImportFrom: dict[str_nameDOTname, list[tuple[ast_Identifier, ast_Identifier | None]]] = defaultdict(list)
53
52
  self.listImport: list[str_nameDOTname] = []
@@ -77,8 +76,6 @@ class LedgerOfImports:
77
76
  self.type_ignores.extend(type_ignores)
78
77
 
79
78
  def addImportFrom_asStr(self, moduleWithLogicalPath: str_nameDOTname, name: ast_Identifier, asname: ast_Identifier | None = None, type_ignores: list[ast.TypeIgnore] | None = None) -> None:
80
- if moduleWithLogicalPath not in self.dictionaryImportFrom:
81
- self.dictionaryImportFrom[moduleWithLogicalPath] = []
82
79
  self.dictionaryImportFrom[moduleWithLogicalPath].append((name, asname))
83
80
  if type_ignores:
84
81
  self.type_ignores.extend(type_ignores)
@@ -131,7 +128,8 @@ class LedgerOfImports:
131
128
  Parameters:
132
129
  *fromLedger: One or more other `LedgerOfImports` objects from which to merge.
133
130
  """
134
- self.dictionaryImportFrom = updateExtendPolishDictionaryLists(self.dictionaryImportFrom, *(ledger.dictionaryImportFrom for ledger in fromLedger), destroyDuplicates=True, reorderLists=True)
131
+ updatedDictionary = updateExtendPolishDictionaryLists(self.dictionaryImportFrom, *(ledger.dictionaryImportFrom for ledger in fromLedger), destroyDuplicates=True, reorderLists=True)
132
+ self.dictionaryImportFrom = defaultdict(list, updatedDictionary)
135
133
  for ledger in fromLedger:
136
134
  self.listImport.extend(ledger.listImport)
137
135
  self.type_ignores.extend(ledger.type_ignores)
@@ -175,22 +173,21 @@ class IngredientsModule:
175
173
  """
176
174
  Assemble a complete Python module from its constituent AST components.
177
175
 
178
- IngredientsModule provides a structured container for all elements needed to
179
- generate a complete Python module, including:
176
+ IngredientsModule provides a structured container for all elements needed to generate a complete Python module,
177
+ including:
180
178
 
181
- 1. Import statements aggregated from all module components
182
- 2. Prologue code that runs before function definitions
183
- 3. Function definitions with their dependencies
184
- 4. Epilogue code that runs after function definitions
185
- 5. Entry point code executed when the module runs as a script
186
- 6. Type ignores and other annotations
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.
187
185
 
188
- This class enables programmatic assembly of Python modules with a clear
189
- separation between different structural elements, while maintaining the
190
- proper ordering and relationships between components.
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.
191
188
 
192
- The modular design allows transformations to be applied to specific parts
193
- of a module while preserving the overall structure.
189
+ The modular design allows transformations to be applied to specific parts of a module while preserving the overall
190
+ structure.
194
191
 
195
192
  Parameters:
196
193
  ingredientsFunction (None): One or more `IngredientsFunction` that will appended to `listIngredientsFunctions`.
@@ -315,22 +312,20 @@ class RecipeSynthesizeFlow:
315
312
  """
316
313
  Configure the generation of new modules, including Numba-accelerated code modules.
317
314
 
318
- RecipeSynthesizeFlow defines the complete blueprint for transforming an original
319
- Python algorithm into an optimized, accelerated implementation. It specifies:
315
+ RecipeSynthesizeFlow defines the complete blueprint for transforming an original Python algorithm into an optimized,
316
+ accelerated implementation. It specifies:
320
317
 
321
- 1. Source code locations and identifiers
322
- 2. Target code locations and identifiers
323
- 3. Naming conventions for generated modules and functions
324
- 4. File system paths for output files
325
- 5. Import relationships between components
318
+ 1. Source code locations and identifiers.
319
+ 2. Target code locations and identifiers.
320
+ 3. Naming conventions for generated modules and functions.
321
+ 4. File system paths for output files.
322
+ 5. Import relationships between components.
326
323
 
327
- This configuration class serves as a single source of truth for the code generation
328
- process, ensuring consistency across all generated artifacts while enabling
329
- customization of the transformation assembly line.
324
+ This configuration class serves as a single source of truth for the code generation process, ensuring consistency
325
+ across all generated artifacts while enabling customization of the transformation assembly line.
330
326
 
331
- The transformation process uses this configuration to extract functions from the
332
- source module, transform them according to optimization rules, and output
333
- properly structured optimized modules with all necessary imports.
327
+ The transformation process uses this configuration to extract functions from the source module, transform them
328
+ according to optimization rules, and output properly structured optimized modules with all necessary imports.
334
329
  """
335
330
  # ========================================
336
331
  # Source
@@ -449,7 +444,7 @@ class ShatteredDataclass:
449
444
  fragments4AssignmentOrParameters: ast.Tuple = dummyTuple
450
445
  """AST tuple used as target for assignment to capture returned fragments."""
451
446
 
452
- ledger: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
447
+ imports: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
453
448
  """Import records for the dataclass and its constituent parts."""
454
449
 
455
450
  list_argAnnotated4ArgumentsSpecification: list[ast.arg] = dataclasses.field(default_factory=list)
@@ -475,3 +470,99 @@ class ShatteredDataclass:
475
470
 
476
471
  signatureReturnAnnotation: ast.Subscript = dummySubscript
477
472
  """tuple-based return type annotation for function definitions."""
473
+
474
+ @dataclasses.dataclass
475
+ class DeReConstructField2ast:
476
+ """
477
+ Transform a dataclass field into AST node representations for code generation.
478
+
479
+ This class extracts and transforms a dataclass Field object into various AST node
480
+ representations needed for code generation. It handles the conversion of field
481
+ attributes, type annotations, and metadata into AST constructs that can be used
482
+ to reconstruct the field in generated code.
483
+
484
+ The class is particularly important for decomposing dataclass fields (like those in
485
+ ComputationState) to enable their use in specialized contexts like Numba-optimized
486
+ functions, where the full dataclass cannot be directly used but its contents need
487
+ to be accessible.
488
+
489
+ Each field is processed according to its type and metadata to create appropriate
490
+ variable declarations, type annotations, and initialization code as AST nodes.
491
+ """
492
+ dataclassesDOTdataclassLogicalPathModule: dataclasses.InitVar[str_nameDOTname]
493
+ dataclassClassDef: dataclasses.InitVar[ast.ClassDef]
494
+ dataclassesDOTdataclassInstance_Identifier: dataclasses.InitVar[ast_Identifier]
495
+ field: dataclasses.InitVar[dataclasses.Field[Any]]
496
+
497
+ ledger: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
498
+
499
+ name: ast_Identifier = dataclasses.field(init=False)
500
+ typeBuffalo: type[Any] | str | Any = dataclasses.field(init=False)
501
+ default: Any | None = dataclasses.field(init=False)
502
+ default_factory: Callable[..., Any] | None = dataclasses.field(init=False)
503
+ repr: bool = dataclasses.field(init=False)
504
+ hash: bool | None = dataclasses.field(init=False)
505
+ init: bool = dataclasses.field(init=False)
506
+ compare: bool = dataclasses.field(init=False)
507
+ metadata: dict[Any, Any] = dataclasses.field(init=False)
508
+ kw_only: bool = dataclasses.field(init=False)
509
+
510
+ astName: ast.Name = dataclasses.field(init=False)
511
+ ast_keyword_field__field: ast.keyword = dataclasses.field(init=False)
512
+ ast_nameDOTname: ast.Attribute = dataclasses.field(init=False)
513
+ astAnnotation: ast.expr = dataclasses.field(init=False)
514
+ ast_argAnnotated: ast.arg = dataclasses.field(init=False)
515
+ astAnnAssignConstructor: ast.AnnAssign|ast.Assign = dataclasses.field(init=False)
516
+ Z0Z_hack: tuple[ast.AnnAssign|ast.Assign, str] = dataclasses.field(init=False)
517
+
518
+ def __post_init__(self, dataclassesDOTdataclassLogicalPathModule: str_nameDOTname, dataclassClassDef: ast.ClassDef, dataclassesDOTdataclassInstance_Identifier: ast_Identifier, field: dataclasses.Field[Any]) -> None:
519
+ self.compare = field.compare
520
+ self.default = field.default if field.default is not dataclasses.MISSING else None
521
+ self.default_factory = field.default_factory if field.default_factory is not dataclasses.MISSING else None
522
+ self.hash = field.hash
523
+ self.init = field.init
524
+ self.kw_only = field.kw_only if field.kw_only is not dataclasses.MISSING else False
525
+ self.metadata = dict(field.metadata)
526
+ self.name = field.name
527
+ self.repr = field.repr
528
+ self.typeBuffalo = field.type
529
+
530
+ self.astName = Make.Name(self.name)
531
+ self.ast_keyword_field__field = Make.keyword(self.name, self.astName)
532
+ self.ast_nameDOTname = Make.Attribute(Make.Name(dataclassesDOTdataclassInstance_Identifier), self.name)
533
+
534
+ sherpa = NodeTourist(ifThis.isAnnAssign_targetIs(ifThis.isName_Identifier(self.name)), Then.extractIt(DOT.annotation)).captureLastMatch(dataclassClassDef)
535
+ if sherpa is None: raise raiseIfNoneGitHubIssueNumber3
536
+ else: self.astAnnotation = sherpa
537
+
538
+ self.ast_argAnnotated = Make.arg(self.name, self.astAnnotation)
539
+
540
+ dtype = self.metadata.get('dtype', None)
541
+ if dtype:
542
+ moduleWithLogicalPath: str_nameDOTname = 'numpy'
543
+ annotationType = 'ndarray'
544
+ self.ledger.addImportFrom_asStr(moduleWithLogicalPath, annotationType)
545
+ self.ledger.addImportFrom_asStr(moduleWithLogicalPath, 'dtype')
546
+ axesSubscript = Make.Subscript(Make.Name('tuple'), Make.Name('uint8'))
547
+ dtype_asnameName: ast.Name = self.astAnnotation # type: ignore
548
+ if dtype_asnameName.id == 'Array3D':
549
+ axesSubscript = Make.Subscript(Make.Name('tuple'), Make.Tuple([Make.Name('uint8'), Make.Name('uint8'), Make.Name('uint8')]))
550
+ ast_expr = Make.Subscript(Make.Name(annotationType), Make.Tuple([axesSubscript, Make.Subscript(Make.Name('dtype'), dtype_asnameName)]))
551
+ constructor = 'array'
552
+ self.ledger.addImportFrom_asStr(moduleWithLogicalPath, constructor)
553
+ dtypeIdentifier: ast_Identifier = dtype.__name__
554
+ self.ledger.addImportFrom_asStr(moduleWithLogicalPath, dtypeIdentifier, dtype_asnameName.id)
555
+ self.astAnnAssignConstructor = Make.AnnAssign(self.astName, ast_expr, Make.Call(Make.Name(constructor), list_astKeywords=[Make.keyword('dtype', dtype_asnameName)]))
556
+ self.astAnnAssignConstructor = Make.Assign([self.astName], Make.Call(Make.Name(constructor), list_astKeywords=[Make.keyword('dtype', dtype_asnameName)]))
557
+ self.Z0Z_hack = (self.astAnnAssignConstructor, 'array')
558
+ elif isinstance(self.astAnnotation, ast.Name):
559
+ self.astAnnAssignConstructor = Make.AnnAssign(self.astName, self.astAnnotation, Make.Call(self.astAnnotation, [Make.Constant(-1)]))
560
+ self.Z0Z_hack = (self.astAnnAssignConstructor, 'scalar')
561
+ elif isinstance(self.astAnnotation, ast.Subscript):
562
+ elementConstructor: ast_Identifier = self.metadata['elementConstructor']
563
+ self.ledger.addImportFrom_asStr(dataclassesDOTdataclassLogicalPathModule, elementConstructor)
564
+ takeTheTuple: ast.Tuple = deepcopy(self.astAnnotation.slice) # type: ignore
565
+ self.astAnnAssignConstructor = Make.AnnAssign(self.astName, self.astAnnotation, takeTheTuple)
566
+ self.Z0Z_hack = (self.astAnnAssignConstructor, elementConstructor)
567
+ if isinstance(self.astAnnotation, ast.Name):
568
+ self.ledger.addImportFrom_asStr(dataclassesDOTdataclassLogicalPathModule, self.astAnnotation.id) # pyright: ignore [reportUnknownArgumentType, reportUnknownMemberType, reportIJustCalledATypeGuardMethod_WTF]