mapFolding 0.8.6__py3-none-any.whl → 0.9.1__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 +60 -13
- mapFolding/basecamp.py +32 -17
- mapFolding/beDRY.py +4 -5
- mapFolding/oeis.py +94 -7
- mapFolding/someAssemblyRequired/RecipeJob.py +103 -0
- mapFolding/someAssemblyRequired/__init__.py +71 -50
- mapFolding/someAssemblyRequired/_theTypes.py +11 -15
- mapFolding/someAssemblyRequired/_tool_Make.py +36 -9
- mapFolding/someAssemblyRequired/_tool_Then.py +59 -25
- mapFolding/someAssemblyRequired/_toolboxAntecedents.py +159 -272
- mapFolding/someAssemblyRequired/_toolboxContainers.py +155 -70
- mapFolding/someAssemblyRequired/_toolboxPython.py +168 -44
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +154 -39
- mapFolding/someAssemblyRequired/toolboxNumba.py +72 -230
- mapFolding/someAssemblyRequired/transformationTools.py +370 -141
- mapFolding/syntheticModules/{numbaCount_doTheNeedful.py → numbaCount.py} +7 -4
- mapFolding/theDao.py +19 -16
- mapFolding/theSSOT.py +165 -62
- mapFolding/toolboxFilesystem.py +1 -1
- mapfolding-0.9.1.dist-info/METADATA +177 -0
- mapfolding-0.9.1.dist-info/RECORD +47 -0
- tests/__init__.py +44 -0
- tests/conftest.py +75 -7
- tests/test_computations.py +92 -10
- tests/test_filesystem.py +32 -33
- tests/test_other.py +0 -1
- tests/test_tasks.py +1 -1
- mapFolding/someAssemblyRequired/newInliner.py +0 -22
- mapfolding-0.8.6.dist-info/METADATA +0 -190
- mapfolding-0.8.6.dist-info/RECORD +0 -47
- {mapfolding-0.8.6.dist-info → mapfolding-0.9.1.dist-info}/WHEEL +0 -0
- {mapfolding-0.8.6.dist-info → mapfolding-0.9.1.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.8.6.dist-info → mapfolding-0.9.1.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.8.6.dist-info → mapfolding-0.9.1.dist-info}/top_level.txt +0 -0
|
@@ -1,331 +1,226 @@
|
|
|
1
|
-
|
|
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.
|
|
5
|
+
It contains two primary classes:
|
|
6
|
+
|
|
7
|
+
1. DOT: Provides consistent accessor methods for AST node attributes across different
|
|
8
|
+
node types, simplifying the access to node properties.
|
|
9
|
+
|
|
10
|
+
2. ifThis: Contains predicate functions for matching AST nodes based on various criteria,
|
|
11
|
+
enabling precise targeting of nodes for analysis or transformation.
|
|
12
|
+
|
|
13
|
+
These utilities form the foundation of the pattern-matching component in the AST
|
|
14
|
+
manipulation framework, working in conjunction with the NodeChanger and NodeTourist
|
|
15
|
+
classes to enable precise and targeted code transformations.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from collections.abc import Callable
|
|
2
19
|
from mapFolding.someAssemblyRequired import (
|
|
3
|
-
ast_expr_Slice,
|
|
4
20
|
ast_Identifier,
|
|
5
|
-
Ima_funcTypeUNEDITED,
|
|
6
21
|
astClassHasDOTnameNotName,
|
|
7
|
-
astClassOptionallyHasDOTnameNotName,
|
|
8
22
|
astClassHasDOTtarget,
|
|
23
|
+
astClassHasDOTtargetAttributeNameSubscript,
|
|
24
|
+
astClassHasDOTtarget_expr,
|
|
9
25
|
astClassHasDOTvalue,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
TypeCertified,
|
|
26
|
+
astClassHasDOTvalue_expr,
|
|
27
|
+
astClassOptionallyHasDOTnameNotName,
|
|
28
|
+
astClassHasDOTvalue_exprNone,
|
|
14
29
|
)
|
|
15
|
-
from typing import Any,
|
|
30
|
+
from typing import Any, overload, TypeGuard
|
|
16
31
|
import ast
|
|
17
32
|
|
|
18
|
-
class NotMyProblem(Exception):
|
|
19
|
-
pass
|
|
20
|
-
|
|
21
33
|
class DOT:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def annotation(node: ast.AnnAssign) -> ImaAnnotationType:...
|
|
25
|
-
@staticmethod
|
|
26
|
-
@overload
|
|
27
|
-
def annotation(node: ast.arg) -> ImaAnnotationType | None:...
|
|
28
|
-
@staticmethod
|
|
29
|
-
def annotation(node: ast.AnnAssign | ast.arg) -> ImaAnnotationType | None:
|
|
30
|
-
return cast(ImaAnnotationType, node.annotation)
|
|
31
|
-
# fu = node.annotation
|
|
32
|
-
# if fu is None:
|
|
33
|
-
# return None
|
|
34
|
-
# else:
|
|
35
|
-
# fu = cast(ImaAnnotationType, node.annotation)
|
|
36
|
-
# return fu
|
|
37
|
-
@staticmethod
|
|
38
|
-
def func(node: ast.Call) -> Ima_funcTypeUNEDITED | ast.expr:
|
|
39
|
-
return node.func
|
|
40
|
-
@staticmethod
|
|
41
|
-
def id(node: ast.Name) -> ast_Identifier:
|
|
42
|
-
return node.id
|
|
43
|
-
@staticmethod
|
|
44
|
-
def name(node: astClassHasDOTnameNotName | astClassOptionallyHasDOTnameNotName) -> ast_Identifier:
|
|
45
|
-
if isinstance(node, astClassHasDOTnameNotName):
|
|
46
|
-
return node.name
|
|
47
|
-
try:
|
|
48
|
-
identifier = node.name
|
|
49
|
-
if identifier is None:
|
|
50
|
-
raise NotMyProblem
|
|
51
|
-
return identifier
|
|
52
|
-
except AttributeError:
|
|
53
|
-
raise NotMyProblem
|
|
34
|
+
"""
|
|
35
|
+
Access attributes and sub-nodes of AST elements via consistent accessor methods.
|
|
54
36
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
try:
|
|
60
|
-
return node.name
|
|
61
|
-
except AttributeError:
|
|
62
|
-
return None
|
|
37
|
+
The DOT class provides static methods to access specific attributes of different
|
|
38
|
+
types of AST nodes in a consistent way. This simplifies attribute access across
|
|
39
|
+
various node types and improves code readability by abstracting the underlying
|
|
40
|
+
AST structure details.
|
|
63
41
|
|
|
64
|
-
|
|
42
|
+
DOT is designed for safe, read-only access to node properties, unlike the grab
|
|
43
|
+
class which is designed for modifying node attributes.
|
|
44
|
+
"""
|
|
65
45
|
@staticmethod
|
|
66
46
|
@overload
|
|
67
|
-
def annotation(
|
|
47
|
+
def annotation(node: ast.AnnAssign) -> ast.expr:...
|
|
68
48
|
@staticmethod
|
|
69
49
|
@overload
|
|
70
|
-
def annotation(
|
|
71
|
-
@staticmethod
|
|
72
|
-
def annotation(predicate: Callable[[ImaAnnotationType], TypeGuard[ImaAnnotationType] | ast.AST | ast_Identifier | bool]) -> Callable[[ast.AnnAssign | ast.arg], TypeGuard[ast.AnnAssign] | TypeGuard[ast.arg] | ast.AST | ast_Identifier | bool]:
|
|
73
|
-
@overload
|
|
74
|
-
def workhorse(node: ast.AnnAssign | ast.arg) -> ast.AST | ast_Identifier:...
|
|
75
|
-
@overload
|
|
76
|
-
def workhorse(node: ast.AnnAssign | ast.arg) -> TypeGuard[ast.AnnAssign] | TypeGuard[ast.arg] | bool:...
|
|
77
|
-
def workhorse(node: ast.AnnAssign | ast.arg) -> TypeGuard[ast.AnnAssign] | TypeGuard[ast.arg] | ast.AST | ast_Identifier | bool:
|
|
78
|
-
ImaAnnotation = node.annotation
|
|
79
|
-
if ImaAnnotation is None: return False
|
|
80
|
-
assert be.Attribute(ImaAnnotation) or be.Constant(ImaAnnotation) or be.Name(ImaAnnotation) or be.Subscript(ImaAnnotation)
|
|
81
|
-
# assert be.Annotation(ImaAnnotation)
|
|
82
|
-
return predicate(ImaAnnotation)
|
|
83
|
-
return workhorse
|
|
50
|
+
def annotation(node: ast.arg) -> ast.expr | None:...
|
|
84
51
|
@staticmethod
|
|
85
|
-
|
|
86
|
-
|
|
52
|
+
def annotation(node: ast.AnnAssign | ast.arg) -> ast.expr | None:
|
|
53
|
+
return node.annotation
|
|
54
|
+
|
|
87
55
|
@staticmethod
|
|
88
56
|
@overload
|
|
89
|
-
def arg(
|
|
90
|
-
@staticmethod
|
|
91
|
-
def arg(predicate: Callable[[ast_Identifier], TypeGuard[ast_Identifier] | ast.AST | ast_Identifier | bool]) -> Callable[[ast.arg | ast.keyword], TypeGuard[ast.arg] | TypeGuard[ast.keyword] | ast.AST | ast_Identifier | bool]:
|
|
92
|
-
@overload
|
|
93
|
-
def workhorse(node: ast.arg | ast.keyword) -> ast.AST | ast_Identifier:...
|
|
94
|
-
@overload
|
|
95
|
-
def workhorse(node: ast.arg | ast.keyword) -> TypeGuard[ast.arg] | TypeGuard[ast.keyword] | bool:...
|
|
96
|
-
def workhorse(node: ast.arg | ast.keyword) -> TypeGuard[ast.arg] | TypeGuard[ast.keyword] | ast.AST | ast_Identifier | bool:
|
|
97
|
-
Ima_arg = node.arg
|
|
98
|
-
if Ima_arg is None: return False
|
|
99
|
-
return predicate(Ima_arg)
|
|
100
|
-
return workhorse
|
|
101
|
-
@staticmethod
|
|
102
|
-
def asname(predicate: Callable[[ast_Identifier | None], TypeGuard[ast_Identifier] | bool]) -> Callable[[ast.alias], TypeGuard[ast.alias] | bool]:
|
|
103
|
-
return lambda node: predicate(node.asname)
|
|
104
|
-
@staticmethod
|
|
105
|
-
def attr(predicate: Callable[[ast_Identifier], TypeGuard[ast_Identifier] | bool]) -> Callable[[ast.Attribute], TypeGuard[ast.Attribute] | bool]:
|
|
106
|
-
return lambda node: predicate(node.attr)
|
|
107
|
-
@staticmethod
|
|
108
|
-
def func(predicate: Callable[[ast.AST], TypeGuard[ast.AST] | bool]) -> Callable[[ast.Call], TypeGuard[ast.Call] | bool]:
|
|
109
|
-
return lambda node: predicate(node.func)
|
|
57
|
+
def arg(node: ast.arg) -> ast_Identifier:...
|
|
110
58
|
@staticmethod
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
@staticmethod
|
|
114
|
-
def module(predicate: Callable[[ast_Identifier | None], TypeGuard[ast_Identifier] | bool]) -> Callable[[ast.ImportFrom], TypeGuard[ast.ImportFrom] | bool]:
|
|
115
|
-
return lambda node: predicate(node.module)
|
|
116
|
-
@staticmethod
|
|
117
|
-
def name(predicate: Callable[[ast_Identifier], TypeGuard[ast_Identifier] | bool]) -> Callable[[astClassHasDOTnameNotName], TypeGuard[astClassHasDOTnameNotName] | bool]:
|
|
118
|
-
return lambda node: predicate(node.name)
|
|
119
|
-
@staticmethod
|
|
120
|
-
def slice(predicate: Callable[[ast_expr_Slice], TypeGuard[ast_expr_Slice] | bool]) -> Callable[[ast.Subscript], TypeGuard[ast.Subscript] | bool]:
|
|
121
|
-
return lambda node: predicate(node.slice)
|
|
122
|
-
@staticmethod
|
|
123
|
-
def target(predicate: Callable[[ast.AST], TypeGuard[ast.AST] | bool]) -> Callable[[astClassHasDOTtarget], TypeGuard[astClassHasDOTtarget] | bool]:
|
|
124
|
-
return lambda node: predicate(node.target)
|
|
59
|
+
@overload
|
|
60
|
+
def arg(node: ast.keyword) -> ast_Identifier | None:...
|
|
125
61
|
@staticmethod
|
|
126
|
-
def
|
|
127
|
-
|
|
128
|
-
ImaValue = node.value
|
|
129
|
-
if ImaValue is None: return False
|
|
130
|
-
return predicate(ImaValue)
|
|
131
|
-
return workhorse
|
|
62
|
+
def arg(node: ast.arg | ast.keyword) -> ast_Identifier | None:
|
|
63
|
+
return node.arg
|
|
132
64
|
|
|
133
|
-
class be:
|
|
134
65
|
@staticmethod
|
|
135
|
-
def
|
|
136
|
-
|
|
137
|
-
return isinstance(node, antecedent)
|
|
138
|
-
return workhorse
|
|
66
|
+
def attr(node: ast.Attribute) -> ast_Identifier:
|
|
67
|
+
return node.attr
|
|
139
68
|
@staticmethod
|
|
140
|
-
def
|
|
141
|
-
|
|
142
|
-
@staticmethod
|
|
143
|
-
def arg(node: TypeCertified) -> TypeGuard[ast.arg]: return be._typeCertified(ast.arg)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
144
|
-
@staticmethod
|
|
145
|
-
def Assign(node: TypeCertified) -> TypeGuard[ast.Assign]: return be._typeCertified(ast.Assign)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
146
|
-
@staticmethod
|
|
147
|
-
def Attribute(node: TypeCertified) -> TypeGuard[ast.Attribute]: return be._typeCertified(ast.Attribute)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
148
|
-
@staticmethod
|
|
149
|
-
def AugAssign(node: TypeCertified) -> TypeGuard[ast.AugAssign]: return be._typeCertified(ast.AugAssign)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
150
|
-
@staticmethod
|
|
151
|
-
def BoolOp(node: TypeCertified) -> TypeGuard[ast.BoolOp]: return be._typeCertified(ast.BoolOp)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
152
|
-
@staticmethod
|
|
153
|
-
def Call(node: TypeCertified) -> TypeGuard[ast.Call]: return be._typeCertified(ast.Call)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
154
|
-
@staticmethod
|
|
155
|
-
def ClassDef(node: TypeCertified) -> TypeGuard[ast.ClassDef]: return be._typeCertified(ast.ClassDef)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
69
|
+
def func(node: ast.Call) -> ast.expr:
|
|
70
|
+
return node.func
|
|
156
71
|
@staticmethod
|
|
157
|
-
def
|
|
72
|
+
def id(node: ast.Name) -> ast_Identifier:
|
|
73
|
+
return node.id
|
|
74
|
+
|
|
158
75
|
@staticmethod
|
|
159
|
-
|
|
76
|
+
@overload
|
|
77
|
+
def name(node: astClassHasDOTnameNotName) -> ast_Identifier:...
|
|
160
78
|
@staticmethod
|
|
161
|
-
|
|
79
|
+
@overload
|
|
80
|
+
def name(node: astClassOptionallyHasDOTnameNotName) -> ast_Identifier | None:...
|
|
162
81
|
@staticmethod
|
|
163
|
-
def
|
|
82
|
+
def name(node: astClassHasDOTnameNotName | astClassOptionallyHasDOTnameNotName) -> ast_Identifier | None:
|
|
83
|
+
return node.name
|
|
84
|
+
|
|
164
85
|
@staticmethod
|
|
165
|
-
|
|
86
|
+
@overload
|
|
87
|
+
def target(node: ast.NamedExpr) -> ast.Name:...
|
|
166
88
|
@staticmethod
|
|
167
|
-
|
|
89
|
+
@overload
|
|
90
|
+
def target(node: astClassHasDOTtarget_expr) -> ast.expr:...
|
|
168
91
|
@staticmethod
|
|
169
|
-
|
|
92
|
+
@overload
|
|
93
|
+
def target(node: astClassHasDOTtargetAttributeNameSubscript) -> ast.Attribute | ast.Name | ast.Subscript:...
|
|
170
94
|
@staticmethod
|
|
171
|
-
def
|
|
95
|
+
def target(node: astClassHasDOTtarget) -> ast.Attribute | ast.expr | ast.Name | ast.Subscript:
|
|
96
|
+
return node.target
|
|
97
|
+
|
|
172
98
|
@staticmethod
|
|
173
|
-
|
|
99
|
+
@overload
|
|
100
|
+
def value(node: ast.Constant) -> Any:...
|
|
174
101
|
@staticmethod
|
|
175
|
-
|
|
102
|
+
@overload
|
|
103
|
+
def value(node: ast.MatchSingleton) -> bool | None:...
|
|
176
104
|
@staticmethod
|
|
177
|
-
|
|
105
|
+
@overload
|
|
106
|
+
def value(node: astClassHasDOTvalue_expr) -> ast.expr:...
|
|
178
107
|
@staticmethod
|
|
179
|
-
|
|
108
|
+
@overload
|
|
109
|
+
def value(node: astClassHasDOTvalue_exprNone) -> ast.expr | None:...
|
|
180
110
|
@staticmethod
|
|
181
|
-
def
|
|
111
|
+
def value(node: astClassHasDOTvalue) -> Any | ast.expr | bool | None:
|
|
112
|
+
return node.value
|
|
182
113
|
|
|
183
114
|
class ifThis:
|
|
115
|
+
"""
|
|
116
|
+
Provide predicate functions for matching and filtering AST nodes based on various criteria.
|
|
117
|
+
|
|
118
|
+
The ifThis class contains static methods that generate predicate functions used to test
|
|
119
|
+
whether AST nodes match specific criteria. These predicates can be used with NodeChanger
|
|
120
|
+
and NodeTourist to identify and process specific patterns in the AST.
|
|
121
|
+
|
|
122
|
+
The class provides predicates for matching various node types, attributes, identifiers,
|
|
123
|
+
and structural patterns, enabling precise targeting of AST elements for analysis or
|
|
124
|
+
transformation.
|
|
125
|
+
"""
|
|
184
126
|
@staticmethod
|
|
185
|
-
def
|
|
186
|
-
return lambda node: node ==
|
|
187
|
-
@staticmethod
|
|
188
|
-
def isAssignAndTargets0Is(targets0Predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
|
|
189
|
-
"""node is Assign and node.targets[0] matches `targets0Predicate`."""
|
|
190
|
-
return lambda node: be.Assign(node) and targets0Predicate(node.targets[0])
|
|
191
|
-
@staticmethod
|
|
192
|
-
def isAssignAndValueIs(valuePredicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.Assign] | bool]:
|
|
193
|
-
"""node is ast.Assign and node.value matches `valuePredicate`.
|
|
194
|
-
Parameters:
|
|
195
|
-
valuePredicate: Function that evaluates the value of the assignment
|
|
196
|
-
Returns:
|
|
197
|
-
predicate: matches assignments with values meeting the criteria
|
|
198
|
-
"""
|
|
199
|
-
return lambda node: be.Assign(node) and 又.value(valuePredicate)(node)
|
|
200
|
-
@staticmethod
|
|
201
|
-
def isFunctionDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.FunctionDef] | bool]:
|
|
202
|
-
return lambda node: be.FunctionDef(node) and 又.name(ifThis._Identifier(identifier))(node)
|
|
203
|
-
@staticmethod
|
|
204
|
-
def isArgument_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.arg | ast.keyword] | bool]:
|
|
205
|
-
return lambda node: (be.arg(node) or be.keyword(node)) and 又.arg(ifThis._Identifier(identifier))(node)
|
|
127
|
+
def _Identifier(identifier: ast_Identifier) -> Callable[[ast_Identifier | None], TypeGuard[ast_Identifier] | bool]:
|
|
128
|
+
return lambda node: node == identifier
|
|
206
129
|
@staticmethod
|
|
207
|
-
def
|
|
208
|
-
|
|
209
|
-
|
|
130
|
+
def _nested_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute | ast.Starred | ast.Subscript] | bool]:
|
|
131
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.Attribute | ast.Starred | ast.Subscript] | bool:
|
|
132
|
+
return ifThis.isName_Identifier(identifier)(node) or ifThis.isAttribute_Identifier(identifier)(node) or ifThis.isSubscript_Identifier(identifier)(node) or ifThis.isStarred_Identifier(identifier)(node)
|
|
133
|
+
return workhorse
|
|
134
|
+
|
|
210
135
|
@staticmethod
|
|
211
136
|
def is_arg_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.arg] | bool]:
|
|
212
137
|
"""see also `isArgument_Identifier`"""
|
|
213
|
-
return lambda node:
|
|
138
|
+
return lambda node: isinstance(node, ast.arg) and ifThis._Identifier(identifier)(DOT.arg(node))
|
|
214
139
|
@staticmethod
|
|
215
|
-
def
|
|
216
|
-
|
|
140
|
+
def is_keyword_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.keyword] | bool]:
|
|
141
|
+
"""see also `isArgument_Identifier`"""
|
|
142
|
+
return lambda node: isinstance(node, ast.keyword) and ifThis._Identifier(identifier)(DOT.arg(node))
|
|
143
|
+
|
|
217
144
|
@staticmethod
|
|
218
|
-
def
|
|
219
|
-
|
|
145
|
+
def isAnnAssign_targetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
|
|
146
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.AnnAssign] | bool:
|
|
147
|
+
return isinstance(node, ast.AnnAssign) and targetPredicate(DOT.target(node))
|
|
148
|
+
return workhorse
|
|
149
|
+
|
|
220
150
|
@staticmethod
|
|
221
|
-
def
|
|
222
|
-
return
|
|
151
|
+
def isArgument_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.arg | ast.keyword] | bool]:
|
|
152
|
+
return lambda node: (isinstance(node, ast.arg) or isinstance(node, ast.keyword)) and ifThis._Identifier(identifier)(DOT.arg(node))
|
|
153
|
+
|
|
223
154
|
@staticmethod
|
|
224
|
-
def
|
|
225
|
-
|
|
155
|
+
def isAssignAndTargets0Is(targets0Predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
|
|
156
|
+
"""node is Assign and node.targets[0] matches `targets0Predicate`."""
|
|
157
|
+
return lambda node: isinstance(node, ast.Assign) and targets0Predicate(node.targets[0])
|
|
226
158
|
@staticmethod
|
|
227
|
-
def
|
|
228
|
-
|
|
159
|
+
def isAssignAndValueIs(valuePredicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.Assign] | bool]:
|
|
160
|
+
"""node is ast.Assign and node.value matches `valuePredicate`. """
|
|
161
|
+
return lambda node: isinstance(node, ast.Assign) and valuePredicate(DOT.value(node))
|
|
162
|
+
|
|
229
163
|
@staticmethod
|
|
230
|
-
def
|
|
231
|
-
|
|
232
|
-
|
|
164
|
+
def isAttribute_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
|
|
165
|
+
"""node is `ast.Attribute` and the top-level `ast.Name` is `identifier`"""
|
|
166
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.Attribute]:
|
|
167
|
+
return isinstance(node, ast.Attribute) and ifThis._nested_Identifier(identifier)(DOT.value(node))
|
|
233
168
|
return workhorse
|
|
234
169
|
@staticmethod
|
|
235
|
-
def
|
|
236
|
-
|
|
237
|
-
|
|
170
|
+
def isAttributeName(node: ast.AST) -> TypeGuard[ast.Attribute]:
|
|
171
|
+
""" Displayed as Name.attribute."""
|
|
172
|
+
return isinstance(node, ast.Attribute) and isinstance(DOT.value(node), ast.Name)
|
|
173
|
+
@staticmethod
|
|
174
|
+
def isAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
|
|
175
|
+
return lambda node: ifThis.isAttributeName(node) and ifThis.isName_Identifier(namespace)(DOT.value(node)) and ifThis._Identifier(identifier)(DOT.attr(node))
|
|
176
|
+
|
|
238
177
|
@staticmethod
|
|
239
|
-
def isAugAssign_targetIs(targetPredicate: Callable[[
|
|
240
|
-
def workhorse(node:
|
|
241
|
-
return
|
|
178
|
+
def isAugAssign_targetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AugAssign] | bool]:
|
|
179
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.AugAssign] | bool:
|
|
180
|
+
return isinstance(node, ast.AugAssign) and targetPredicate(DOT.target(node))
|
|
242
181
|
return workhorse
|
|
243
182
|
|
|
244
183
|
@staticmethod
|
|
245
|
-
def
|
|
246
|
-
return
|
|
184
|
+
def isCall_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
185
|
+
return lambda node: isinstance(node, ast.Call) and ifThis.isName_Identifier(identifier)(DOT.func(node))
|
|
247
186
|
@staticmethod
|
|
248
|
-
def
|
|
249
|
-
return lambda node:
|
|
187
|
+
def isCallAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
188
|
+
return lambda node: isinstance(node, ast.Call) and ifThis.isAttributeNamespace_Identifier(namespace, identifier)(DOT.func(node))
|
|
250
189
|
@staticmethod
|
|
251
|
-
def
|
|
252
|
-
return
|
|
190
|
+
def isCallToName(node: ast.AST) -> TypeGuard[ast.Call]:
|
|
191
|
+
return isinstance(node, ast.Call) and isinstance(DOT.func(node), ast.Name)
|
|
192
|
+
|
|
253
193
|
@staticmethod
|
|
254
|
-
def
|
|
255
|
-
return
|
|
194
|
+
def isClassDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.ClassDef] | bool]:
|
|
195
|
+
return lambda node: isinstance(node, ast.ClassDef) and ifThis._Identifier(identifier)(DOT.name(node))
|
|
256
196
|
|
|
257
|
-
# ================================================================
|
|
258
|
-
# Nested identifier
|
|
259
197
|
@staticmethod
|
|
260
|
-
def
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return workhorse
|
|
198
|
+
def isFunctionDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.FunctionDef] | bool]:
|
|
199
|
+
return lambda node: isinstance(node, ast.FunctionDef) and ifThis._Identifier(identifier)(DOT.name(node))
|
|
200
|
+
|
|
264
201
|
@staticmethod
|
|
265
|
-
def
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
return be.Attribute(node) and 又.value(ifThis._nestedJunction_Identifier(identifier))(node)
|
|
269
|
-
return workhorse
|
|
202
|
+
def isName_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Name] | bool]:
|
|
203
|
+
return lambda node: isinstance(node, ast.Name) and ifThis._Identifier(identifier)(DOT.id(node))
|
|
204
|
+
|
|
270
205
|
@staticmethod
|
|
271
206
|
def isStarred_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Starred] | bool]:
|
|
272
207
|
"""node is `ast.Starred` and the top-level `ast.Name` is `identifier`"""
|
|
273
|
-
def workhorse(node:
|
|
274
|
-
return
|
|
208
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.Starred]:
|
|
209
|
+
return isinstance(node, ast.Starred) and ifThis._nested_Identifier(identifier)(DOT.value(node))
|
|
275
210
|
return workhorse
|
|
276
211
|
@staticmethod
|
|
277
212
|
def isSubscript_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Subscript] | bool]:
|
|
278
213
|
"""node is `ast.Subscript` and the top-level `ast.Name` is `identifier`"""
|
|
279
|
-
def workhorse(node:
|
|
280
|
-
return
|
|
281
|
-
return workhorse
|
|
282
|
-
# ================================================================
|
|
283
|
-
|
|
284
|
-
@staticmethod
|
|
285
|
-
def Z0Z_unparseIs(astAST: ast.AST) -> Callable[[ast.AST], bool]:
|
|
286
|
-
def workhorse(node: TypeCertified) -> bool: return ast.unparse(node) == ast.unparse(astAST) # pyright: ignore [reportInvalidTypeVarUse]
|
|
214
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.Subscript]:
|
|
215
|
+
return isinstance(node, ast.Subscript) and ifThis._nested_Identifier(identifier)(DOT.value(node))
|
|
287
216
|
return workhorse
|
|
288
217
|
|
|
289
|
-
# ================================================================
|
|
290
|
-
# NOT used
|
|
291
|
-
# TODO Does this work?
|
|
292
|
-
@staticmethod
|
|
293
|
-
def Z0Z_matchesAtLeast1Descendant(predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
|
|
294
|
-
"""Create a predicate that returns True if any descendant of the node matches the given predicate."""
|
|
295
|
-
return lambda node: not ifThis.matchesNoDescendant(predicate)(node)
|
|
296
|
-
# ================================================================
|
|
297
|
-
# MORE function inlining
|
|
298
|
-
@staticmethod
|
|
299
|
-
def onlyReturnAnyCompare(astFunctionDef: ast.AST) -> TypeGuard[ast.FunctionDef] | bool:
|
|
300
|
-
return be.FunctionDef(astFunctionDef) and len(astFunctionDef.body) == 1 and ifThis.isReturnAnyCompare(astFunctionDef.body[0])
|
|
301
|
-
# For function inlining
|
|
302
|
-
@staticmethod
|
|
303
|
-
def onlyReturnUnaryOp(astFunctionDef: ast.AST) -> TypeGuard[ast.FunctionDef] | bool:
|
|
304
|
-
return be.FunctionDef(astFunctionDef) and len(astFunctionDef.body) == 1 and ifThis.isReturnUnaryOp(astFunctionDef.body[0])
|
|
305
|
-
# ================================================================
|
|
306
|
-
# These are used by other functions
|
|
307
|
-
@staticmethod
|
|
308
|
-
def isCallAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
309
|
-
return lambda node: be.Call(node) and 又.func(ifThis.isAttributeNamespace_Identifier(namespace, identifier))(node)
|
|
310
|
-
@staticmethod
|
|
311
|
-
def isName_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Name] | bool]:
|
|
312
|
-
return lambda node: be.Name(node) and 又.id(ifThis._Identifier(identifier))(node)
|
|
313
|
-
@staticmethod
|
|
314
|
-
def isCall_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
315
|
-
return lambda node: be.Call(node) and 又.func(ifThis.isName_Identifier(identifier))(node)
|
|
316
|
-
# ================================================================
|
|
317
|
-
@staticmethod
|
|
318
|
-
def CallDoesNotCallItself(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
319
|
-
"""If `namespace` is not applicable to your case, then call with `namespace=""`."""
|
|
320
|
-
return lambda node: ifThis.matchesMeButNotAnyDescendant(ifThis.CallReallyIs(namespace, identifier))(node)
|
|
321
218
|
@staticmethod
|
|
322
219
|
def matchesMeButNotAnyDescendant(predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
|
|
323
|
-
"""Create a predicate that returns True if the node matches but none of its descendants match the predicate."""
|
|
324
220
|
return lambda node: predicate(node) and ifThis.matchesNoDescendant(predicate)(node)
|
|
325
221
|
@staticmethod
|
|
326
222
|
def matchesNoDescendant(predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
|
|
327
|
-
|
|
328
|
-
def workhorse(node: TypeCertified) -> bool: # pyright: ignore [reportInvalidTypeVarUse]
|
|
223
|
+
def workhorse(node: ast.AST) -> bool:
|
|
329
224
|
for descendant in ast.walk(node):
|
|
330
225
|
if descendant is not node and predicate(descendant):
|
|
331
226
|
return False
|
|
@@ -333,26 +228,18 @@ class ifThis:
|
|
|
333
228
|
return workhorse
|
|
334
229
|
|
|
335
230
|
@staticmethod
|
|
336
|
-
def
|
|
337
|
-
return
|
|
338
|
-
|
|
339
|
-
def isAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
|
|
340
|
-
return lambda node: ifThis.isAttributeName(node) and 又.value(ifThis.isName_Identifier(namespace))(node) and 又.attr(ifThis._Identifier(identifier))(node)
|
|
341
|
-
@staticmethod
|
|
342
|
-
def _Identifier(identifier: ast_Identifier) -> Callable[[ast_Identifier | None], TypeGuard[ast_Identifier] | bool]:
|
|
343
|
-
return lambda node: node == identifier
|
|
344
|
-
@staticmethod
|
|
345
|
-
def isAttributeName(node: TypeCertified) -> TypeGuard[ast.Attribute]: # pyright: ignore [reportInvalidTypeVarUse]
|
|
346
|
-
""" Displayed as Name.attribute."""
|
|
347
|
-
return be.Attribute(node) and 又.value(be.Name)(node)
|
|
231
|
+
def Z0Z_unparseIs(astAST: ast.AST) -> Callable[[ast.AST], bool]:
|
|
232
|
+
def workhorse(node: ast.AST) -> bool: return ast.unparse(node) == ast.unparse(astAST)
|
|
233
|
+
return workhorse
|
|
348
234
|
|
|
235
|
+
|
|
236
|
+
class be:
|
|
349
237
|
@staticmethod
|
|
350
|
-
def
|
|
351
|
-
return
|
|
238
|
+
def Call(node: ast.AST) -> TypeGuard[ast.Call]:
|
|
239
|
+
return isinstance(node, ast.Call)
|
|
352
240
|
@staticmethod
|
|
353
|
-
def
|
|
354
|
-
return
|
|
355
|
-
# This bullshit is for the crappy function inliner I made.
|
|
241
|
+
def Name(node: ast.AST) -> TypeGuard[ast.Name]:
|
|
242
|
+
return isinstance(node, ast.Name)
|
|
356
243
|
@staticmethod
|
|
357
|
-
def
|
|
358
|
-
return
|
|
244
|
+
def Return(node: ast.AST) -> TypeGuard[ast.Return]:
|
|
245
|
+
return isinstance(node, ast.Return)
|