mapFolding 0.9.4__py3-none-any.whl → 0.10.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.
Files changed (42) 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 +143 -42
  9. mapFolding/someAssemblyRequired/__init__.py +38 -49
  10. mapFolding/someAssemblyRequired/_astTypes.py +117 -0
  11. mapFolding/someAssemblyRequired/_theTypes.py +12 -41
  12. mapFolding/someAssemblyRequired/_toolBe.py +524 -0
  13. mapFolding/someAssemblyRequired/_toolDOT.py +493 -0
  14. mapFolding/someAssemblyRequired/_toolGrab.py +653 -0
  15. mapFolding/someAssemblyRequired/_toolIfThis.py +193 -0
  16. mapFolding/someAssemblyRequired/_toolMake.py +339 -0
  17. mapFolding/someAssemblyRequired/_toolThen.py +63 -0
  18. mapFolding/someAssemblyRequired/_toolboxAST.py +3 -3
  19. mapFolding/someAssemblyRequired/_toolboxContainers.py +124 -29
  20. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +274 -0
  21. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +12 -11
  22. mapFolding/someAssemblyRequired/toolboxNumba.py +4 -28
  23. mapFolding/someAssemblyRequired/transformationTools.py +46 -155
  24. mapFolding/syntheticModules/daoOfMapFolding.py +74 -0
  25. mapFolding/syntheticModules/dataPacking.py +1 -1
  26. mapFolding/syntheticModules/theorem2Numba.py +2 -8
  27. mapFolding/syntheticModules/theorem2Trimmed.py +43 -0
  28. mapFolding/toolFactory/astFactory.py +493 -0
  29. mapFolding/toolFactory/astFactory_annex.py +63 -0
  30. mapFolding/toolFactory/astFactory_docstrings.py +63 -0
  31. {mapfolding-0.9.4.dist-info → mapfolding-0.10.0.dist-info}/METADATA +2 -1
  32. mapfolding-0.10.0.dist-info/RECORD +66 -0
  33. {mapfolding-0.9.4.dist-info → mapfolding-0.10.0.dist-info}/WHEEL +1 -1
  34. tests/test_computations.py +1 -1
  35. mapFolding/Z0Z_flowControl.py +0 -117
  36. mapFolding/someAssemblyRequired/_tool_Make.py +0 -134
  37. mapFolding/someAssemblyRequired/_tool_Then.py +0 -157
  38. mapFolding/someAssemblyRequired/_toolboxAntecedents.py +0 -387
  39. mapfolding-0.9.4.dist-info/RECORD +0 -57
  40. {mapfolding-0.9.4.dist-info → mapfolding-0.10.0.dist-info}/entry_points.txt +0 -0
  41. {mapfolding-0.9.4.dist-info → mapfolding-0.10.0.dist-info}/licenses/LICENSE +0 -0
  42. {mapfolding-0.9.4.dist-info → mapfolding-0.10.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,193 @@
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 collections.abc import Callable
23
+ from mapFolding.someAssemblyRequired import (
24
+ ast_Identifier,
25
+ Be,
26
+ DOT,
27
+ ImaCallToName,
28
+ )
29
+ from typing import Any, TypeGuard
30
+ import ast
31
+
32
+ class IfThis:
33
+ """
34
+ Provide predicate functions for matching and filtering AST nodes based on various criteria.
35
+
36
+ The ifThis class contains static methods that generate predicate functions used to test whether AST nodes match
37
+ specific criteria. These predicates can be used with NodeChanger and NodeTourist to identify and process specific
38
+ patterns in the AST.
39
+
40
+ The class provides predicates for matching various node types, attributes, identifiers, and structural patterns,
41
+ enabling precise targeting of AST elements for analysis or transformation.
42
+ """
43
+ @staticmethod
44
+ def _Identifier(identifier: ast_Identifier) -> Callable[[ast_Identifier | None], TypeGuard[ast_Identifier] | bool]:
45
+ return lambda node: node == identifier
46
+ @staticmethod
47
+ def _nested_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute | ast.Starred | ast.Subscript] | bool]:
48
+ def workhorse(node: ast.AST) -> TypeGuard[ast.Attribute | ast.Starred | ast.Subscript] | bool:
49
+ return IfThis.isName_Identifier(identifier)(node) or IfThis.isAttribute_Identifier(identifier)(node) or IfThis.isSubscript_Identifier(identifier)(node) or IfThis.isStarred_Identifier(identifier)(node)
50
+ return workhorse
51
+
52
+ @staticmethod
53
+ def is_arg_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.arg] | bool]:
54
+ """see also `isArgument_Identifier`"""
55
+ return lambda node: Be.arg(node) and IfThis._Identifier(identifier)(DOT.arg(node))
56
+ @staticmethod
57
+ def is_keyword_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.keyword] | bool]:
58
+ """see also `isArgument_Identifier`"""
59
+ return lambda node: Be.keyword(node) and IfThis._Identifier(identifier)(DOT.arg(node))
60
+
61
+ @staticmethod
62
+ def isAnnAssign_targetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
63
+ def workhorse(node: ast.AST) -> TypeGuard[ast.AnnAssign] | bool:
64
+ return Be.AnnAssign(node) and targetPredicate(DOT.target(node))
65
+ return workhorse
66
+
67
+ @staticmethod
68
+ def isArgument_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.arg | ast.keyword] | bool]:
69
+ return lambda node: (Be.arg(node) or Be.keyword(node)) and IfThis._Identifier(identifier)(DOT.arg(node))
70
+
71
+ @staticmethod
72
+ def isAssignAndTargets0Is(targets0Predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
73
+ """node is Assign and node.targets[0] matches `targets0Predicate`."""
74
+ return lambda node: Be.Assign(node) and targets0Predicate(node.targets[0])
75
+ @staticmethod
76
+ def isAssignAndValueIs(valuePredicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.Assign] | bool]:
77
+ """node is ast.Assign and node.value matches `valuePredicate`. """
78
+ return lambda node: Be.Assign(node) and valuePredicate(DOT.value(node))
79
+
80
+ @staticmethod
81
+ def isAttribute_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
82
+ """node is `ast.Attribute` and the top-level `ast.Name` is `identifier`"""
83
+ def workhorse(node: ast.AST) -> TypeGuard[ast.Attribute]:
84
+ return Be.Attribute(node) and IfThis._nested_Identifier(identifier)(DOT.value(node))
85
+ return workhorse
86
+ @staticmethod
87
+ def isAttributeName(node: ast.AST) -> TypeGuard[ast.Attribute]:
88
+ """ Displayed as Name.attribute."""
89
+ return Be.Attribute(node) and Be.Name(DOT.value(node))
90
+ @staticmethod
91
+ def isAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
92
+ return lambda node: IfThis.isAttributeName(node) and IfThis.isName_Identifier(namespace)(DOT.value(node)) and IfThis._Identifier(identifier)(DOT.attr(node))
93
+
94
+ @staticmethod
95
+ def isAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
96
+ return lambda node: (Be.Compare(node)
97
+ and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
98
+ and Be.Gt(node.ops[0])
99
+ and IfThis.isConstant_value(0)(node.comparators[0]))
100
+
101
+ @staticmethod
102
+ def isUnaryNotAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.UnaryOp] | bool]:
103
+ return lambda node: (Be.UnaryOp(node)
104
+ and Be.Not(node.op)
105
+ and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(node.operand))
106
+
107
+ @staticmethod
108
+ def isIfUnaryNotAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.If] | bool]:
109
+ return lambda node: (Be.If(node)
110
+ and IfThis.isUnaryNotAttributeNamespace_Identifier(namespace, identifier)(node.test))
111
+
112
+ @staticmethod
113
+ def isIfAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.If] | bool]:
114
+ return lambda node: (Be.If(node)
115
+ and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
116
+
117
+ @staticmethod
118
+ def isWhileAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.While] | bool]:
119
+ return lambda node: (Be.While(node)
120
+ and IfThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
121
+
122
+ @staticmethod
123
+ def isAttributeNamespace_IdentifierLessThanOrEqual(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
124
+ return lambda node: (Be.Compare(node)
125
+ and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
126
+ and Be.LtE(node.ops[0]))
127
+
128
+ @staticmethod
129
+ def isAugAssign_targetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AugAssign] | bool]:
130
+ def workhorse(node: ast.AST) -> TypeGuard[ast.AugAssign] | bool:
131
+ return Be.AugAssign(node) and targetPredicate(DOT.target(node))
132
+ return workhorse
133
+
134
+ @staticmethod
135
+ def isCall_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ImaCallToName] | bool]:
136
+ def workhorse(node: ast.AST) -> TypeGuard[ImaCallToName] | bool:
137
+ return IfThis.isCallToName(node) and IfThis._Identifier(identifier)(DOT.id(DOT.func(node)))
138
+ return workhorse
139
+
140
+ @staticmethod
141
+ def isCallAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
142
+ def workhorse(node: ast.AST) -> TypeGuard[ast.Call] | bool:
143
+ return Be.Call(node) and IfThis.isAttributeNamespace_Identifier(namespace, identifier)(DOT.func(node))
144
+ return workhorse
145
+ @staticmethod
146
+ def isCallToName(node: ast.AST) -> TypeGuard[ImaCallToName]:
147
+ return Be.Call(node) and Be.Name(DOT.func(node))
148
+
149
+ @staticmethod
150
+ def isClassDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.ClassDef] | bool]:
151
+ return lambda node: Be.ClassDef(node) and IfThis._Identifier(identifier)(DOT.name(node))
152
+
153
+ @staticmethod
154
+ def isConstant_value(value: Any) -> Callable[[ast.AST], TypeGuard[ast.Constant] | bool]:
155
+ return lambda node: Be.Constant(node) and DOT.value(node) == value
156
+
157
+ @staticmethod
158
+ def isFunctionDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.FunctionDef] | bool]:
159
+ return lambda node: Be.FunctionDef(node) and IfThis._Identifier(identifier)(DOT.name(node))
160
+
161
+ @staticmethod
162
+ def isName_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Name] | bool]:
163
+ return lambda node: Be.Name(node) and IfThis._Identifier(identifier)(DOT.id(node))
164
+
165
+ @staticmethod
166
+ def isStarred_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Starred] | bool]:
167
+ """node is `ast.Starred` and the top-level `ast.Name` is `identifier`"""
168
+ def workhorse(node: ast.AST) -> TypeGuard[ast.Starred]:
169
+ return Be.Starred(node) and IfThis._nested_Identifier(identifier)(DOT.value(node))
170
+ return workhorse
171
+ @staticmethod
172
+ def isSubscript_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Subscript] | bool]:
173
+ """node is `ast.Subscript` and the top-level `ast.Name` is `identifier`"""
174
+ def workhorse(node: ast.AST) -> TypeGuard[ast.Subscript]:
175
+ return Be.Subscript(node) and IfThis._nested_Identifier(identifier)(DOT.value(node))
176
+ return workhorse
177
+
178
+ @staticmethod
179
+ def matchesMeButNotAnyDescendant(predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
180
+ return lambda node: predicate(node) and IfThis.matchesNoDescendant(predicate)(node)
181
+ @staticmethod
182
+ def matchesNoDescendant(predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
183
+ def workhorse(node: ast.AST) -> bool:
184
+ for descendant in ast.walk(node):
185
+ if descendant is not node and predicate(descendant):
186
+ return False
187
+ return True
188
+ return workhorse
189
+
190
+ @staticmethod
191
+ def Z0Z_unparseIs(astAST: ast.AST) -> Callable[[ast.AST], bool]:
192
+ def workhorse(node: ast.AST) -> bool: return ast.unparse(node) == ast.unparse(astAST)
193
+ return workhorse
@@ -0,0 +1,339 @@
1
+ """This file is generated automatically, so changes to this file will be lost."""
2
+ from collections.abc import Sequence
3
+ from mapFolding import astDOTParamSpec, astDOTTryStar, astDOTTypeAlias, astDOTTypeVar, astDOTTypeVarTuple, astDOTtype_param
4
+ from mapFolding.someAssemblyRequired import ast_Identifier, ast_expr_Slice, intORstr, intORstrORtype_params, intORtype_params, str_nameDOTname
5
+ from typing import Any, Literal
6
+ import ast
7
+
8
+ class Make:
9
+ """
10
+ Almost all parameters described here are only accessible through a method's `**keywordArguments` parameter.
11
+
12
+ Parameters:
13
+ context (ast.Load()): Are you loading from, storing to, or deleting the identifier? The `context` (also, `ctx`) value is `ast.Load()`, `ast.Store()`, or `ast.Del()`.
14
+ col_offset (0): int Position information specifying the column where an AST node begins.
15
+ end_col_offset (None): int|None Position information specifying the column where an AST node ends.
16
+ end_lineno (None): int|None Position information specifying the line number where an AST node ends.
17
+ level (0): int Module import depth level that controls relative vs absolute imports. Default 0 indicates absolute import.
18
+ lineno: int Position information manually specifying the line number where an AST node begins.
19
+ kind (None): str|None Used for type annotations in limited cases.
20
+ type_comment (None): str|None "type_comment is an optional string with the type annotation as a comment." or `# type: ignore`.
21
+ type_params: list[ast.type_param] Type parameters for generic type definitions.
22
+
23
+ The `ast._Attributes`, lineno, col_offset, end_lineno, and end_col_offset, hold position information; however, they are, importantly, _not_ `ast._fields`.
24
+ """
25
+
26
+ @staticmethod
27
+ def alias(name: ast_Identifier, asName: ast_Identifier | None=None, **keywordArguments: int) -> ast.alias:
28
+ return ast.alias(name, asName, **keywordArguments)
29
+
30
+ @staticmethod
31
+ def AnnAssign(target: ast.Name | ast.Attribute | ast.Subscript, annotation: ast.expr, value: ast.expr | None, **keywordArguments: int) -> ast.AnnAssign:
32
+ return ast.AnnAssign(target, annotation, value, **keywordArguments, simple=int(isinstance(target, ast.Name)))
33
+
34
+ @staticmethod
35
+ def arg(arg: ast_Identifier, annotation: ast.expr | None, **keywordArguments: intORstr) -> ast.arg:
36
+ return ast.arg(arg, annotation, **keywordArguments)
37
+
38
+ @staticmethod
39
+ def arguments(posonlyargs: list[ast.arg]=[], args: list[ast.arg]=[], vararg: ast.arg | None=None, kwonlyargs: list[ast.arg]=[], kw_defaults: Sequence[ast.expr | None]=[None], kwarg: ast.arg | None=None, defaults: Sequence[ast.expr]=[], **keywordArguments: int) -> ast.arguments:
40
+ return ast.arguments(posonlyargs, args, vararg, kwonlyargs, list(kw_defaults), kwarg, list(defaults), **keywordArguments)
41
+
42
+ @staticmethod
43
+ def Assert(test: ast.expr, msg: ast.expr | None, **keywordArguments: int) -> ast.Assert:
44
+ return ast.Assert(test, msg, **keywordArguments)
45
+
46
+ @staticmethod
47
+ def Assign(targets: Sequence[ast.expr], value: ast.expr, **keywordArguments: intORstr) -> ast.Assign:
48
+ return ast.Assign(list(targets), value, **keywordArguments)
49
+
50
+ @staticmethod
51
+ def AsyncFor(target: ast.expr, iter: ast.expr, body: Sequence[ast.stmt], orElse: Sequence[ast.stmt]=[], **keywordArguments: intORstr) -> ast.AsyncFor:
52
+ return ast.AsyncFor(target, iter, list(body), list(orElse), **keywordArguments)
53
+
54
+ @staticmethod
55
+ def AsyncFunctionDef(name: ast_Identifier, args: ast.arguments, body: Sequence[ast.stmt], decorator_list: Sequence[ast.expr]=[], returns: ast.expr | None=None, **keywordArguments: intORstrORtype_params) -> ast.AsyncFunctionDef:
56
+ return ast.AsyncFunctionDef(name, args, list(body), list(decorator_list), returns, **keywordArguments)
57
+
58
+ @staticmethod
59
+ def AsyncWith(items: list[ast.withitem], body: Sequence[ast.stmt], **keywordArguments: intORstr) -> ast.AsyncWith:
60
+ return ast.AsyncWith(items, list(body), **keywordArguments)
61
+
62
+ @staticmethod
63
+ def Attribute(value: ast.expr, *attribute: ast_Identifier, context: ast.expr_context=ast.Load(), **keywordArguments: int) -> ast.Attribute:
64
+ """ If two `ast_Identifier` are joined by a dot `.`, they are _usually_ an `ast.Attribute`, but see `ast.ImportFrom`.
65
+ Parameters:
66
+ value: the part before the dot (e.g., `ast.Name`.)
67
+ attribute: an `ast_Identifier` after a dot `.`; you can pass multiple `attribute` and they will be chained together.
68
+ """
69
+
70
+ def addDOTattribute(chain: ast.expr, identifier: ast_Identifier, context: ast.expr_context, **keywordArguments: int) -> ast.Attribute:
71
+ return ast.Attribute(value=chain, attr=identifier, ctx=context, **keywordArguments)
72
+ buffaloBuffalo = addDOTattribute(value, attribute[0], context, **keywordArguments)
73
+ for identifier in attribute[1:None]:
74
+ buffaloBuffalo = addDOTattribute(buffaloBuffalo, identifier, context, **keywordArguments)
75
+ return buffaloBuffalo
76
+
77
+ @staticmethod
78
+ def AugAssign(target: ast.Name | ast.Attribute | ast.Subscript, op: ast.operator, value: ast.expr, **keywordArguments: int) -> ast.AugAssign:
79
+ return ast.AugAssign(target, op, value, **keywordArguments)
80
+
81
+ @staticmethod
82
+ def Await(value: ast.expr, **keywordArguments: int) -> ast.Await:
83
+ return ast.Await(value, **keywordArguments)
84
+
85
+ @staticmethod
86
+ def BinOp(left: ast.expr, op: ast.operator, right: ast.expr, **keywordArguments: int) -> ast.BinOp:
87
+ return ast.BinOp(left, op, right, **keywordArguments)
88
+
89
+ @staticmethod
90
+ def BoolOp(op: ast.boolop, values: Sequence[ast.expr], **keywordArguments: int) -> ast.BoolOp:
91
+ return ast.BoolOp(op, list(values), **keywordArguments)
92
+
93
+ @staticmethod
94
+ def Call(callee: ast.expr, args: Sequence[ast.expr]=[], list_keyword: list[ast.keyword]=[], **keywordArguments: int) -> ast.Call:
95
+ return ast.Call(callee, list(args), list_keyword, **keywordArguments)
96
+
97
+ @staticmethod
98
+ def ClassDef(name: ast_Identifier, bases: Sequence[ast.expr], list_keyword: list[ast.keyword]=[], body: Sequence[ast.stmt]=[], decorator_list: Sequence[ast.expr]=[], **keywordArguments: intORtype_params) -> ast.ClassDef:
99
+ return ast.ClassDef(name, list(bases), list_keyword, list(body), list(decorator_list), **keywordArguments)
100
+
101
+ @staticmethod
102
+ def Compare(left: ast.expr, ops: Sequence[ast.cmpop], comparators: Sequence[ast.expr], **keywordArguments: int) -> ast.Compare:
103
+ return ast.Compare(left, list(ops), list(comparators), **keywordArguments)
104
+
105
+ @staticmethod
106
+ def comprehension(target: ast.expr, iter: ast.expr, ifs: Sequence[ast.expr], is_async: int, **keywordArguments: int) -> ast.comprehension:
107
+ return ast.comprehension(target, iter, list(ifs), is_async, **keywordArguments)
108
+
109
+ @staticmethod
110
+ def Constant(value: Any, **keywordArguments: intORstr) -> ast.Constant:
111
+ return ast.Constant(value, **keywordArguments)
112
+
113
+ @staticmethod
114
+ def Delete(targets: Sequence[ast.expr], **keywordArguments: int) -> ast.Delete:
115
+ return ast.Delete(list(targets), **keywordArguments)
116
+
117
+ @staticmethod
118
+ def Dict(keys: Sequence[ast.expr | None], values: Sequence[ast.expr], **keywordArguments: int) -> ast.Dict:
119
+ return ast.Dict(list(keys), list(values), **keywordArguments)
120
+
121
+ @staticmethod
122
+ def DictComp(key: ast.expr, value: ast.expr, generators: list[ast.comprehension], **keywordArguments: int) -> ast.DictComp:
123
+ return ast.DictComp(key, value, generators, **keywordArguments)
124
+
125
+ @staticmethod
126
+ def ExceptHandler(type: ast.expr | None, name: ast_Identifier | None, body: Sequence[ast.stmt], **keywordArguments: int) -> ast.ExceptHandler:
127
+ return ast.ExceptHandler(type, name, list(body), **keywordArguments)
128
+
129
+ @staticmethod
130
+ def Expr(value: ast.expr, **keywordArguments: int) -> ast.Expr:
131
+ return ast.Expr(value, **keywordArguments)
132
+
133
+ @staticmethod
134
+ def Expression(body: ast.expr) -> ast.Expression:
135
+ return ast.Expression(body)
136
+
137
+ @staticmethod
138
+ def For(target: ast.expr, iter: ast.expr, body: Sequence[ast.stmt], orElse: Sequence[ast.stmt]=[], **keywordArguments: intORstr) -> ast.For:
139
+ return ast.For(target, iter, list(body), list(orElse), **keywordArguments)
140
+
141
+ @staticmethod
142
+ def FormattedValue(value: ast.expr, conversion: int, format_spec: ast.expr | None, **keywordArguments: int) -> ast.FormattedValue:
143
+ return ast.FormattedValue(value, conversion, format_spec, **keywordArguments)
144
+
145
+ @staticmethod
146
+ def FunctionDef(name: ast_Identifier, args: ast.arguments, body: Sequence[ast.stmt], decorator_list: Sequence[ast.expr]=[], returns: ast.expr | None=None, **keywordArguments: intORstrORtype_params) -> ast.FunctionDef:
147
+ return ast.FunctionDef(name, args, list(body), list(decorator_list), returns, **keywordArguments)
148
+
149
+ @staticmethod
150
+ def FunctionType(argtypes: Sequence[ast.expr], returns: ast.expr) -> ast.FunctionType:
151
+ return ast.FunctionType(list(argtypes), returns)
152
+
153
+ @staticmethod
154
+ def GeneratorExp(elt: ast.expr, generators: list[ast.comprehension], **keywordArguments: int) -> ast.GeneratorExp:
155
+ return ast.GeneratorExp(elt, generators, **keywordArguments)
156
+
157
+ @staticmethod
158
+ def Global(names: list[ast_Identifier], **keywordArguments: int) -> ast.Global:
159
+ return ast.Global(names, **keywordArguments)
160
+
161
+ @staticmethod
162
+ def If(test: ast.expr, body: Sequence[ast.stmt], orElse: Sequence[ast.stmt]=[], **keywordArguments: int) -> ast.If:
163
+ return ast.If(test, list(body), list(orElse), **keywordArguments)
164
+
165
+ @staticmethod
166
+ def IfExp(test: ast.expr, body: ast.expr, orElse: ast.expr, **keywordArguments: int) -> ast.IfExp:
167
+ return ast.IfExp(test, body, orElse, **keywordArguments)
168
+
169
+ @staticmethod
170
+ def Import(moduleWithLogicalPath: str_nameDOTname, asName: ast_Identifier | None=None, **keywordArguments: int) -> ast.Import:
171
+ return ast.Import(names=[Make.alias(moduleWithLogicalPath, asName)], **keywordArguments)
172
+
173
+ @staticmethod
174
+ def ImportFrom(module: ast_Identifier | None, list_alias: list[ast.alias], **keywordArguments: int) -> ast.ImportFrom:
175
+ return ast.ImportFrom(module, list_alias, **keywordArguments, level=0)
176
+
177
+ @staticmethod
178
+ def Interactive(body: Sequence[ast.stmt]) -> ast.Interactive:
179
+ return ast.Interactive(list(body))
180
+
181
+ @staticmethod
182
+ def JoinedStr(values: Sequence[ast.expr], **keywordArguments: int) -> ast.JoinedStr:
183
+ return ast.JoinedStr(list(values), **keywordArguments)
184
+
185
+ @staticmethod
186
+ def keyword(arg: ast_Identifier | None, value: ast.expr, **keywordArguments: int) -> ast.keyword:
187
+ return ast.keyword(arg, value, **keywordArguments)
188
+
189
+ @staticmethod
190
+ def Lambda(args: ast.arguments, body: ast.expr, **keywordArguments: int) -> ast.Lambda:
191
+ return ast.Lambda(args, body, **keywordArguments)
192
+
193
+ @staticmethod
194
+ def List(elts: Sequence[ast.expr], context: ast.expr_context=ast.Load(), **keywordArguments: int) -> ast.List:
195
+ return ast.List(list(elts), context, **keywordArguments)
196
+
197
+ @staticmethod
198
+ def ListComp(elt: ast.expr, generators: list[ast.comprehension], **keywordArguments: int) -> ast.ListComp:
199
+ return ast.ListComp(elt, generators, **keywordArguments)
200
+
201
+ @staticmethod
202
+ def Match(subject: ast.expr, cases: list[ast.match_case], **keywordArguments: int) -> ast.Match:
203
+ return ast.Match(subject, cases, **keywordArguments)
204
+
205
+ @staticmethod
206
+ def match_case(pattern: ast.pattern, guard: ast.expr | None, body: Sequence[ast.stmt], **keywordArguments: int) -> ast.match_case:
207
+ return ast.match_case(pattern, guard, list(body), **keywordArguments)
208
+
209
+ @staticmethod
210
+ def MatchAs(pattern: ast.pattern | None, name: ast_Identifier | None, **keywordArguments: int) -> ast.MatchAs:
211
+ return ast.MatchAs(pattern, name, **keywordArguments)
212
+
213
+ @staticmethod
214
+ def MatchClass(cls: ast.expr, patterns: Sequence[ast.pattern], kwd_attrs: list[ast_Identifier], kwd_patterns: Sequence[ast.pattern], **keywordArguments: int) -> ast.MatchClass:
215
+ return ast.MatchClass(cls, list(patterns), kwd_attrs, list(kwd_patterns), **keywordArguments)
216
+
217
+ @staticmethod
218
+ def MatchMapping(keys: Sequence[ast.expr], patterns: Sequence[ast.pattern], rest: ast_Identifier | None, **keywordArguments: int) -> ast.MatchMapping:
219
+ return ast.MatchMapping(list(keys), list(patterns), rest, **keywordArguments)
220
+
221
+ @staticmethod
222
+ def MatchOr(patterns: Sequence[ast.pattern], **keywordArguments: int) -> ast.MatchOr:
223
+ return ast.MatchOr(list(patterns), **keywordArguments)
224
+
225
+ @staticmethod
226
+ def MatchSequence(patterns: Sequence[ast.pattern], **keywordArguments: int) -> ast.MatchSequence:
227
+ return ast.MatchSequence(list(patterns), **keywordArguments)
228
+
229
+ @staticmethod
230
+ def MatchSingleton(value: Literal[True, False] | None, **keywordArguments: int) -> ast.MatchSingleton:
231
+ return ast.MatchSingleton(value, **keywordArguments)
232
+
233
+ @staticmethod
234
+ def MatchStar(name: ast_Identifier | None, **keywordArguments: int) -> ast.MatchStar:
235
+ return ast.MatchStar(name, **keywordArguments)
236
+
237
+ @staticmethod
238
+ def MatchValue(value: ast.expr, **keywordArguments: int) -> ast.MatchValue:
239
+ return ast.MatchValue(value, **keywordArguments)
240
+
241
+ @staticmethod
242
+ def Module(body: Sequence[ast.stmt], type_ignores: list[ast.TypeIgnore]=[]) -> ast.Module:
243
+ return ast.Module(list(body), type_ignores)
244
+
245
+ @staticmethod
246
+ def Name(id: ast_Identifier, context: ast.expr_context=ast.Load(), **keywordArguments: int) -> ast.Name:
247
+ return ast.Name(id, context, **keywordArguments)
248
+
249
+ @staticmethod
250
+ def NamedExpr(target: ast.Name, value: ast.expr, **keywordArguments: int) -> ast.NamedExpr:
251
+ return ast.NamedExpr(target, value, **keywordArguments)
252
+
253
+ @staticmethod
254
+ def Nonlocal(names: list[ast_Identifier], **keywordArguments: int) -> ast.Nonlocal:
255
+ return ast.Nonlocal(names, **keywordArguments)
256
+
257
+ @staticmethod
258
+ def ParamSpec(name: ast_Identifier, default_value: ast.expr | None, **keywordArguments: int) -> astDOTParamSpec:
259
+ return astDOTParamSpec(name, default_value, **keywordArguments)
260
+
261
+ @staticmethod
262
+ def Raise(exc: ast.expr | None, cause: ast.expr | None, **keywordArguments: int) -> ast.Raise:
263
+ return ast.Raise(exc, cause, **keywordArguments)
264
+
265
+ @staticmethod
266
+ def Return(value: ast.expr | None, **keywordArguments: int) -> ast.Return:
267
+ return ast.Return(value, **keywordArguments)
268
+
269
+ @staticmethod
270
+ def Set(elts: Sequence[ast.expr], **keywordArguments: int) -> ast.Set:
271
+ return ast.Set(list(elts), **keywordArguments)
272
+
273
+ @staticmethod
274
+ def SetComp(elt: ast.expr, generators: list[ast.comprehension], **keywordArguments: int) -> ast.SetComp:
275
+ return ast.SetComp(elt, generators, **keywordArguments)
276
+
277
+ @staticmethod
278
+ def Slice(lower: ast.expr | None, upper: ast.expr | None, step: ast.expr | None, **keywordArguments: int) -> ast.Slice:
279
+ return ast.Slice(lower, upper, step, **keywordArguments)
280
+
281
+ @staticmethod
282
+ def Starred(value: ast.expr, context: ast.expr_context=ast.Load(), **keywordArguments: int) -> ast.Starred:
283
+ return ast.Starred(value, context, **keywordArguments)
284
+
285
+ @staticmethod
286
+ def Subscript(value: ast.expr, slice: ast_expr_Slice, context: ast.expr_context=ast.Load(), **keywordArguments: int) -> ast.Subscript:
287
+ return ast.Subscript(value, slice, context, **keywordArguments)
288
+
289
+ @staticmethod
290
+ def Try(body: Sequence[ast.stmt], handlers: list[ast.ExceptHandler], orElse: Sequence[ast.stmt], finalbody: Sequence[ast.stmt]=[], **keywordArguments: int) -> ast.Try:
291
+ return ast.Try(list(body), handlers, list(orElse), list(finalbody), **keywordArguments)
292
+
293
+ @staticmethod
294
+ def TryStar(body: Sequence[ast.stmt], handlers: list[ast.ExceptHandler], orElse: Sequence[ast.stmt], finalbody: Sequence[ast.stmt]=[], **keywordArguments: int) -> astDOTTryStar:
295
+ return astDOTTryStar(list(body), handlers, list(orElse), list(finalbody), **keywordArguments)
296
+
297
+ @staticmethod
298
+ def Tuple(elts: Sequence[ast.expr], context: ast.expr_context=ast.Load(), **keywordArguments: int) -> ast.Tuple:
299
+ return ast.Tuple(list(elts), context, **keywordArguments)
300
+
301
+ @staticmethod
302
+ def TypeAlias(name: ast.Name, type_params: Sequence[astDOTtype_param], value: ast.expr, **keywordArguments: int) -> astDOTTypeAlias:
303
+ return astDOTTypeAlias(name, list(type_params), value, **keywordArguments)
304
+
305
+ @staticmethod
306
+ def TypeIgnore(lineno: int, tag: ast_Identifier, **keywordArguments: int) -> ast.TypeIgnore:
307
+ return ast.TypeIgnore(lineno, tag, **keywordArguments)
308
+
309
+ @staticmethod
310
+ def TypeVar(name: ast_Identifier, bound: ast.expr | None, default_value: ast.expr | None, **keywordArguments: int) -> astDOTTypeVar:
311
+ return astDOTTypeVar(name, bound, default_value, **keywordArguments)
312
+
313
+ @staticmethod
314
+ def TypeVarTuple(name: ast_Identifier, default_value: ast.expr | None, **keywordArguments: int) -> astDOTTypeVarTuple:
315
+ return astDOTTypeVarTuple(name, default_value, **keywordArguments)
316
+
317
+ @staticmethod
318
+ def UnaryOp(op: ast.unaryop, operand: ast.expr, **keywordArguments: int) -> ast.UnaryOp:
319
+ return ast.UnaryOp(op, operand, **keywordArguments)
320
+
321
+ @staticmethod
322
+ def While(test: ast.expr, body: Sequence[ast.stmt], orElse: Sequence[ast.stmt]=[], **keywordArguments: int) -> ast.While:
323
+ return ast.While(test, list(body), list(orElse), **keywordArguments)
324
+
325
+ @staticmethod
326
+ def With(items: list[ast.withitem], body: Sequence[ast.stmt], **keywordArguments: intORstr) -> ast.With:
327
+ return ast.With(items, list(body), **keywordArguments)
328
+
329
+ @staticmethod
330
+ def withitem(context_expr: ast.expr, optional_vars: ast.expr | None, **keywordArguments: int) -> ast.withitem:
331
+ return ast.withitem(context_expr, optional_vars, **keywordArguments)
332
+
333
+ @staticmethod
334
+ def Yield(value: ast.expr | None, **keywordArguments: int) -> ast.Yield:
335
+ return ast.Yield(value, **keywordArguments)
336
+
337
+ @staticmethod
338
+ def YieldFrom(value: ast.expr, **keywordArguments: int) -> ast.YieldFrom:
339
+ return ast.YieldFrom(value, **keywordArguments)
@@ -0,0 +1,63 @@
1
+ """
2
+ AST Node Transformation Actions for Python Code Manipulation
3
+
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
6
+ transform or extract information from AST nodes.
7
+
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.
10
+
11
+ Together, these classes provide a complete system for manipulating AST nodes once they have been identified using
12
+ predicate functions from ifThis.
13
+ """
14
+
15
+ from collections.abc import Callable, Sequence
16
+ from mapFolding.someAssemblyRequired import ast_Identifier, NodeORattribute
17
+ from typing import Any
18
+ import ast
19
+
20
+ class Then:
21
+ """
22
+ Provide action functions that specify what to do with AST nodes that match predicates.
23
+
24
+ The Then class contains static methods that generate action functions used with NodeChanger and NodeTourist to
25
+ transform or extract information from AST nodes that match specific predicates. These actions include node
26
+ replacement, insertion, extraction, and collection operations.
27
+
28
+ When paired with predicates from the ifThis class, Then methods complete the pattern-matching-and-action workflow
29
+ for AST manipulation.
30
+ """
31
+ @staticmethod
32
+ def appendTo(listOfAny: list[Any]) -> Callable[[ast.AST | ast_Identifier], ast.AST | ast_Identifier]:
33
+ def workhorse(node: ast.AST | ast_Identifier) -> ast.AST | ast_Identifier:
34
+ listOfAny.append(node)
35
+ return node
36
+ return workhorse
37
+
38
+ @staticmethod
39
+ def extractIt(node: NodeORattribute) -> NodeORattribute:
40
+ return node
41
+
42
+ @staticmethod
43
+ def insertThisAbove(list_astAST: Sequence[ast.AST]) -> Callable[[ast.AST], Sequence[ast.AST]]:
44
+ return lambda aboveMe: [*list_astAST, aboveMe]
45
+
46
+ @staticmethod
47
+ def insertThisBelow(list_astAST: Sequence[ast.AST]) -> Callable[[ast.AST], Sequence[ast.AST]]:
48
+ return lambda belowMe: [belowMe, *list_astAST]
49
+
50
+ @staticmethod
51
+ def removeIt(_removeMe: ast.AST) -> None:
52
+ return None
53
+
54
+ @staticmethod
55
+ def replaceWith(astAST: NodeORattribute) -> Callable[[NodeORattribute], NodeORattribute]:
56
+ return lambda _replaceMe: astAST
57
+
58
+ @staticmethod
59
+ def updateKeyValueIn(key: Callable[..., Any], value: Callable[..., Any], dictionary: dict[Any, Any]) -> Callable[[ast.AST], dict[Any, Any]]:
60
+ def workhorse(node: ast.AST) -> dict[Any, Any]:
61
+ dictionary.setdefault(key(node), value(node))
62
+ return dictionary
63
+ return workhorse
@@ -1,4 +1,4 @@
1
- from mapFolding.someAssemblyRequired import ast_Identifier, ifThis, IngredientsFunction, LedgerOfImports, NodeTourist, Then
1
+ from mapFolding.someAssemblyRequired import ast_Identifier, IfThis, IngredientsFunction, LedgerOfImports, NodeTourist, Then
2
2
  from mapFolding.theSSOT import raiseIfNoneGitHubIssueNumber3
3
3
  import ast
4
4
 
@@ -38,7 +38,7 @@ def extractClassDef(module: ast.AST, identifier: ast_Identifier) -> ast.ClassDef
38
38
  Returns:
39
39
  astClassDef|None: The matching class definition AST node, or `None` if not found.
40
40
  """
41
- return NodeTourist(ifThis.isClassDef_Identifier(identifier), Then.extractIt).captureLastMatch(module)
41
+ return NodeTourist(IfThis.isClassDef_Identifier(identifier), Then.extractIt).captureLastMatch(module)
42
42
 
43
43
  def extractFunctionDef(module: ast.AST, identifier: ast_Identifier) -> ast.FunctionDef | None:
44
44
  """
@@ -54,4 +54,4 @@ def extractFunctionDef(module: ast.AST, identifier: ast_Identifier) -> ast.Funct
54
54
  Returns:
55
55
  astFunctionDef|None: The matching function definition AST node, or `None` if not found.
56
56
  """
57
- return NodeTourist(ifThis.isFunctionDef_Identifier(identifier), Then.extractIt).captureLastMatch(module)
57
+ return NodeTourist(IfThis.isFunctionDef_Identifier(identifier), Then.extractIt).captureLastMatch(module)