mapFolding 0.9.2__py3-none-any.whl → 0.9.4__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/Z0Z_flowControl.py +117 -0
- mapFolding/__init__.py +28 -26
- mapFolding/basecamp.py +1 -1
- mapFolding/beDRY.py +1 -2
- mapFolding/daoOfMapFolding.py +142 -0
- mapFolding/dataBaskets.py +49 -0
- mapFolding/datatypes.py +21 -0
- mapFolding/oeis.py +1 -2
- mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +226 -0
- mapFolding/someAssemblyRequired/__init__.py +12 -2
- mapFolding/someAssemblyRequired/_theTypes.py +11 -5
- mapFolding/someAssemblyRequired/_tool_Make.py +8 -0
- mapFolding/someAssemblyRequired/_tool_Then.py +44 -1
- mapFolding/someAssemblyRequired/_toolboxAST.py +57 -0
- mapFolding/someAssemblyRequired/_toolboxAntecedents.py +95 -29
- mapFolding/someAssemblyRequired/_toolboxContainers.py +59 -53
- mapFolding/someAssemblyRequired/_toolboxPython.py +52 -50
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +10 -9
- mapFolding/someAssemblyRequired/toolboxNumba.py +1 -1
- mapFolding/someAssemblyRequired/transformationTools.py +40 -58
- mapFolding/syntheticModules/dataPacking.py +25 -0
- mapFolding/syntheticModules/initializeCount.py +49 -0
- mapFolding/syntheticModules/theorem2.py +49 -0
- mapFolding/syntheticModules/theorem2Numba.py +51 -0
- mapFolding/theSSOT.py +13 -21
- {mapfolding-0.9.2.dist-info → mapfolding-0.9.4.dist-info}/METADATA +4 -3
- mapfolding-0.9.4.dist-info/RECORD +57 -0
- {mapfolding-0.9.2.dist-info → mapfolding-0.9.4.dist-info}/WHEEL +1 -1
- tests/__init__.py +2 -2
- tests/conftest.py +7 -7
- tests/test_computations.py +17 -13
- tests/test_tasks.py +2 -2
- mapfolding-0.9.2.dist-info/RECORD +0 -47
- {mapfolding-0.9.2.dist-info → mapfolding-0.9.4.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.9.2.dist-info → mapfolding-0.9.4.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.9.2.dist-info → mapfolding-0.9.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
from mapFolding import raiseIfNoneGitHubIssueNumber3, The
|
|
2
|
+
from mapFolding.someAssemblyRequired import (
|
|
3
|
+
ast_Identifier,
|
|
4
|
+
astModuleToIngredientsFunction,
|
|
5
|
+
be,
|
|
6
|
+
DOT,
|
|
7
|
+
extractFunctionDef,
|
|
8
|
+
grab,
|
|
9
|
+
ifThis,
|
|
10
|
+
IngredientsFunction,
|
|
11
|
+
IngredientsModule,
|
|
12
|
+
LedgerOfImports,
|
|
13
|
+
Make,
|
|
14
|
+
NodeChanger,
|
|
15
|
+
NodeTourist,
|
|
16
|
+
parseLogicalPath2astModule,
|
|
17
|
+
parsePathFilename2astModule,
|
|
18
|
+
Then,
|
|
19
|
+
str_nameDOTname,
|
|
20
|
+
)
|
|
21
|
+
from mapFolding.someAssemblyRequired.toolboxNumba import decorateCallableWithNumba, parametersNumbaLight
|
|
22
|
+
from mapFolding.someAssemblyRequired.transformationTools import (
|
|
23
|
+
inlineFunctionDef,
|
|
24
|
+
removeDataclassFromFunction,
|
|
25
|
+
removeUnusedParameters,
|
|
26
|
+
shatter_dataclassesDOTdataclass,
|
|
27
|
+
unpackDataclassCallFunctionRepackDataclass,
|
|
28
|
+
write_astModule,
|
|
29
|
+
)
|
|
30
|
+
from pathlib import PurePath
|
|
31
|
+
import ast
|
|
32
|
+
|
|
33
|
+
algorithmSourceModuleHARDCODED = 'daoOfMapFolding'
|
|
34
|
+
sourceCallableIdentifierHARDCODED = 'count'
|
|
35
|
+
logicalPathInfixHARDCODED: ast_Identifier = 'syntheticModules'
|
|
36
|
+
theCountingIdentifierHARDCODED: ast_Identifier = 'groupsOfFolds'
|
|
37
|
+
|
|
38
|
+
def makeInitializeGroupsOfFolds():
|
|
39
|
+
callableIdentifierHARDCODED = 'initializeGroupsOfFolds'
|
|
40
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'initializeCount'
|
|
41
|
+
|
|
42
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
43
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
44
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
45
|
+
|
|
46
|
+
callableIdentifier = callableIdentifierHARDCODED
|
|
47
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
48
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
49
|
+
|
|
50
|
+
astModule = parseLogicalPath2astModule(logicalPathSourceModule)
|
|
51
|
+
countInitializeIngredients = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule)
|
|
52
|
+
, LedgerOfImports(astModule))
|
|
53
|
+
|
|
54
|
+
countInitializeIngredients.astFunctionDef.name = callableIdentifier
|
|
55
|
+
|
|
56
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(countInitializeIngredients.astFunctionDef)
|
|
57
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
58
|
+
theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
59
|
+
|
|
60
|
+
findThis = ifThis.isWhileAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
61
|
+
doThat = grab.testAttribute(grab.andDoAllOf([
|
|
62
|
+
grab.opsAttribute(Then.replaceWith([ast.Eq()])), # type: ignore
|
|
63
|
+
grab.leftAttribute(grab.attrAttribute(Then.replaceWith(theCountingIdentifier))) # type: ignore
|
|
64
|
+
]))
|
|
65
|
+
NodeChanger(findThis, doThat).visit(countInitializeIngredients.astFunctionDef.body[0])
|
|
66
|
+
|
|
67
|
+
initializationModule = IngredientsModule(countInitializeIngredients)
|
|
68
|
+
|
|
69
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
70
|
+
|
|
71
|
+
write_astModule(initializationModule, pathFilename, The.packageName)
|
|
72
|
+
|
|
73
|
+
def makeTheorem2():
|
|
74
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'theorem2'
|
|
75
|
+
|
|
76
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
77
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
78
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
79
|
+
|
|
80
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
81
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
82
|
+
|
|
83
|
+
astModule = parseLogicalPath2astModule(logicalPathSourceModule)
|
|
84
|
+
countTheorem2 = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule)
|
|
85
|
+
, LedgerOfImports(astModule))
|
|
86
|
+
|
|
87
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(countTheorem2.astFunctionDef)
|
|
88
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
89
|
+
|
|
90
|
+
findThis = ifThis.isWhileAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
91
|
+
doThat = grab.testAttribute(grab.comparatorsAttribute(Then.replaceWith([Make.Constant(4)]))) # type: ignore
|
|
92
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
93
|
+
|
|
94
|
+
findThis = ifThis.isIfAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
95
|
+
doThat = Then.extractIt(DOT.body)
|
|
96
|
+
insertLeaf = NodeTourist(findThis, doThat).captureLastMatch(countTheorem2.astFunctionDef)
|
|
97
|
+
findThis = ifThis.isIfAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
98
|
+
doThat = Then.replaceWith(insertLeaf)
|
|
99
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
100
|
+
|
|
101
|
+
findThis = ifThis.isAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
102
|
+
doThat = Then.removeIt
|
|
103
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
104
|
+
|
|
105
|
+
findThis = ifThis.isAttributeNamespace_IdentifierLessThanOrEqual(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
106
|
+
doThat = Then.removeIt
|
|
107
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
108
|
+
|
|
109
|
+
theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
110
|
+
doubleTheCount = Make.AugAssign(Make.Attribute(ast.Name(dataclassInstanceIdentifier), theCountingIdentifier), ast.Mult(), Make.Constant(2))
|
|
111
|
+
findThis = be.Return
|
|
112
|
+
doThat = Then.insertThisAbove([doubleTheCount])
|
|
113
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
114
|
+
|
|
115
|
+
moduleTheorem2 = IngredientsModule(countTheorem2)
|
|
116
|
+
|
|
117
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
118
|
+
|
|
119
|
+
write_astModule(moduleTheorem2, pathFilename, The.packageName)
|
|
120
|
+
|
|
121
|
+
return pathFilename
|
|
122
|
+
|
|
123
|
+
def numbaOnTheorem2(pathFilenameSource: PurePath):
|
|
124
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
125
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
126
|
+
countNumbaTheorem2 = astModuleToIngredientsFunction(parsePathFilename2astModule(pathFilenameSource), sourceCallableIdentifier)
|
|
127
|
+
dataclassName: ast.expr | None = NodeTourist(be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(countNumbaTheorem2.astFunctionDef)
|
|
128
|
+
if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
|
|
129
|
+
dataclass_Identifier: ast_Identifier | None = NodeTourist(be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
|
|
130
|
+
if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
131
|
+
|
|
132
|
+
dataclassLogicalPathModule = None
|
|
133
|
+
for moduleWithLogicalPath, listNameTuples in countNumbaTheorem2.imports.dictionaryImportFrom.items():
|
|
134
|
+
for nameTuple in listNameTuples:
|
|
135
|
+
if nameTuple[0] == dataclass_Identifier:
|
|
136
|
+
dataclassLogicalPathModule = moduleWithLogicalPath
|
|
137
|
+
break
|
|
138
|
+
if dataclassLogicalPathModule:
|
|
139
|
+
break
|
|
140
|
+
if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
|
|
141
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(countNumbaTheorem2.astFunctionDef)
|
|
142
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
143
|
+
shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
|
|
144
|
+
|
|
145
|
+
countNumbaTheorem2.imports.update(shatteredDataclass.imports)
|
|
146
|
+
countNumbaTheorem2 = removeDataclassFromFunction(countNumbaTheorem2, shatteredDataclass)
|
|
147
|
+
|
|
148
|
+
countNumbaTheorem2 = removeUnusedParameters(countNumbaTheorem2)
|
|
149
|
+
|
|
150
|
+
countNumbaTheorem2 = decorateCallableWithNumba(countNumbaTheorem2, parametersNumbaLight)
|
|
151
|
+
|
|
152
|
+
moduleNumbaTheorem2 = IngredientsModule(countNumbaTheorem2)
|
|
153
|
+
moduleNumbaTheorem2.removeImportFromModule('numpy')
|
|
154
|
+
|
|
155
|
+
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem + 'Numba')
|
|
156
|
+
|
|
157
|
+
write_astModule(moduleNumbaTheorem2, pathFilename, The.packageName)
|
|
158
|
+
|
|
159
|
+
logicalPath: list[str] = []
|
|
160
|
+
if The.packageName:
|
|
161
|
+
logicalPath.append(The.packageName)
|
|
162
|
+
if logicalPathInfix:
|
|
163
|
+
logicalPath.append(logicalPathInfix)
|
|
164
|
+
logicalPath.append(pathFilename.stem)
|
|
165
|
+
moduleWithLogicalPath: str_nameDOTname = '.'.join(logicalPath)
|
|
166
|
+
|
|
167
|
+
astImportFrom: ast.ImportFrom = Make.ImportFrom(moduleWithLogicalPath, list_astAlias=[Make.alias(countNumbaTheorem2.astFunctionDef.name)])
|
|
168
|
+
|
|
169
|
+
return astImportFrom
|
|
170
|
+
|
|
171
|
+
def makeUnRePackDataclass(astImportFrom: ast.ImportFrom):
|
|
172
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'dataPacking'
|
|
173
|
+
|
|
174
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
175
|
+
sourceCallableIdentifier = The.sourceCallableDispatcher
|
|
176
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
177
|
+
|
|
178
|
+
callableIdentifier = sourceCallableIdentifier
|
|
179
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
180
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
181
|
+
|
|
182
|
+
doTheNeedful: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
|
|
183
|
+
dataclassName: ast.expr | None = NodeTourist(be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(doTheNeedful.astFunctionDef)
|
|
184
|
+
if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
|
|
185
|
+
dataclass_Identifier: ast_Identifier | None = NodeTourist(be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
|
|
186
|
+
if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
187
|
+
|
|
188
|
+
dataclassLogicalPathModule = None
|
|
189
|
+
for moduleWithLogicalPath, listNameTuples in doTheNeedful.imports.dictionaryImportFrom.items():
|
|
190
|
+
for nameTuple in listNameTuples:
|
|
191
|
+
if nameTuple[0] == dataclass_Identifier:
|
|
192
|
+
dataclassLogicalPathModule = moduleWithLogicalPath
|
|
193
|
+
break
|
|
194
|
+
if dataclassLogicalPathModule:
|
|
195
|
+
break
|
|
196
|
+
if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
|
|
197
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(doTheNeedful.astFunctionDef)
|
|
198
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
199
|
+
shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
|
|
200
|
+
|
|
201
|
+
doTheNeedful.imports.update(shatteredDataclass.imports)
|
|
202
|
+
doTheNeedful.imports.addAst(astImportFrom)
|
|
203
|
+
targetCallableIdentifier = astImportFrom.names[0].name
|
|
204
|
+
doTheNeedful = unpackDataclassCallFunctionRepackDataclass(doTheNeedful, targetCallableIdentifier, shatteredDataclass)
|
|
205
|
+
targetFunctionDef = extractFunctionDef(parseLogicalPath2astModule(astImportFrom.module), targetCallableIdentifier) # type: ignore
|
|
206
|
+
if targetFunctionDef is None: raise raiseIfNoneGitHubIssueNumber3
|
|
207
|
+
astTuple: ast.Tuple | None = NodeTourist(be.Return, Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)
|
|
208
|
+
if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
|
|
209
|
+
astTuple.ctx = ast.Store()
|
|
210
|
+
|
|
211
|
+
findThis = ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(targetCallableIdentifier))
|
|
212
|
+
doThat = Then.replaceWith(Make.Assign(listTargets=[astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
|
|
213
|
+
NodeChanger(findThis, doThat).visit(doTheNeedful.astFunctionDef)
|
|
214
|
+
|
|
215
|
+
moduleDoTheNeedful = IngredientsModule(doTheNeedful)
|
|
216
|
+
moduleDoTheNeedful.removeImportFromModule('numpy')
|
|
217
|
+
|
|
218
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
219
|
+
|
|
220
|
+
write_astModule(moduleDoTheNeedful, pathFilename, The.packageName)
|
|
221
|
+
|
|
222
|
+
if __name__ == '__main__':
|
|
223
|
+
makeInitializeGroupsOfFolds()
|
|
224
|
+
pathFilename = makeTheorem2()
|
|
225
|
+
astImportFrom = numbaOnTheorem2(pathFilename)
|
|
226
|
+
makeUnRePackDataclass(astImportFrom)
|
|
@@ -22,7 +22,7 @@ functional implementations into highly-optimized variants with verified correctn
|
|
|
22
22
|
- Recipe configuration for generating optimized code (RecipeSynthesizeFlow)
|
|
23
23
|
- Dataclass decomposition for compatibility (ShatteredDataclass)
|
|
24
24
|
|
|
25
|
-
3. **Optimization
|
|
25
|
+
3. **Optimization assembly lines**
|
|
26
26
|
- General-purpose Numba acceleration (makeNumbaFlow)
|
|
27
27
|
- Job-specific optimization for concrete parameters (makeJobNumba)
|
|
28
28
|
- Specialized component transformation (decorateCallableWithNumba)
|
|
@@ -50,14 +50,18 @@ to verify correctness at each transformation stage through the integrated test s
|
|
|
50
50
|
from mapFolding.someAssemblyRequired._theTypes import (
|
|
51
51
|
ast_expr_Slice as ast_expr_Slice,
|
|
52
52
|
ast_Identifier as ast_Identifier,
|
|
53
|
+
astClassHasDOTbody as astClassHasDOTbody,
|
|
54
|
+
astClassHasDOTbody_expr as astClassHasDOTbody_expr,
|
|
55
|
+
astClassHasDOTbodyList_stmt as astClassHasDOTbodyList_stmt,
|
|
53
56
|
astClassHasDOTnameNotName as astClassHasDOTnameNotName,
|
|
57
|
+
astClassHasDOTnameNotNameAlways as astClassHasDOTnameNotNameAlways,
|
|
58
|
+
astClassHasDOTnameNotNameOptionally as astClassHasDOTnameNotNameOptionally,
|
|
54
59
|
astClassHasDOTtarget as astClassHasDOTtarget,
|
|
55
60
|
astClassHasDOTtarget_expr as astClassHasDOTtarget_expr,
|
|
56
61
|
astClassHasDOTtargetAttributeNameSubscript as astClassHasDOTtargetAttributeNameSubscript,
|
|
57
62
|
astClassHasDOTvalue as astClassHasDOTvalue,
|
|
58
63
|
astClassHasDOTvalue_expr as astClassHasDOTvalue_expr,
|
|
59
64
|
astClassHasDOTvalue_exprNone as astClassHasDOTvalue_exprNone,
|
|
60
|
-
astClassOptionallyHasDOTnameNotName as astClassOptionallyHasDOTnameNotName,
|
|
61
65
|
ImaCallToName as ImaCallToName,
|
|
62
66
|
intORlist_ast_type_paramORstr_orNone as intORlist_ast_type_paramORstr_orNone,
|
|
63
67
|
intORstr_orNone as intORstr_orNone,
|
|
@@ -87,3 +91,9 @@ from mapFolding.someAssemblyRequired._toolboxContainers import (
|
|
|
87
91
|
RecipeSynthesizeFlow as RecipeSynthesizeFlow,
|
|
88
92
|
ShatteredDataclass as ShatteredDataclass,
|
|
89
93
|
)
|
|
94
|
+
|
|
95
|
+
from mapFolding.someAssemblyRequired._toolboxAST import (
|
|
96
|
+
astModuleToIngredientsFunction as astModuleToIngredientsFunction,
|
|
97
|
+
extractClassDef as extractClassDef,
|
|
98
|
+
extractFunctionDef as extractFunctionDef,
|
|
99
|
+
)
|
|
@@ -6,24 +6,30 @@ stuPyd: typing_TypeAlias = str
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
7
|
""" 3.12 new: ast.ParamSpec, ast.type_param, ast.TypeAlias, ast.TypeVar, ast.TypeVarTuple
|
|
8
8
|
3.11 new: ast.TryStar"""
|
|
9
|
-
|
|
9
|
+
astClassHasDOTbodyList_stmt: typing_TypeAlias = ast.AsyncFor | ast.AsyncWith | ast.ClassDef | ast.ExceptHandler | ast.For | ast.FunctionDef | ast.If | ast.Interactive | ast.match_case | ast.Module | ast.Try | ast.TryStar | ast.While | ast.With
|
|
10
|
+
astClassHasDOTnameNotNameAlways: typing_TypeAlias = ast.alias | ast.AsyncFunctionDef | ast.ClassDef | ast.FunctionDef | ast.ParamSpec | ast.TypeVar | ast.TypeVarTuple
|
|
10
11
|
astClassHasDOTvalue_expr: typing_TypeAlias = ast.Assign | ast.Attribute | ast.AugAssign | ast.Await | ast.DictComp | ast.Expr | ast.FormattedValue | ast.keyword | ast.MatchValue | ast.NamedExpr | ast.Starred | ast.Subscript | ast.TypeAlias | ast.YieldFrom
|
|
11
12
|
|
|
12
13
|
else:
|
|
13
|
-
|
|
14
|
+
astClassHasDOTbodyList_stmt = stuPyd
|
|
15
|
+
astClassHasDOTnameNotNameAlways = stuPyd
|
|
14
16
|
astClassHasDOTvalue_expr = stuPyd
|
|
15
17
|
|
|
16
18
|
class ImaCallToName(ast.Call):
|
|
17
19
|
func: ast.Name # pyright: ignore[reportIncompatibleVariableOverride]
|
|
18
|
-
# assert isinstance(ast.Call.func, ast.Name), "
|
|
20
|
+
# assert isinstance(ast.Call.func, ast.Name), "brinkmanship"
|
|
19
21
|
# func: ast.Name
|
|
20
22
|
|
|
23
|
+
astClassHasDOTbody_expr: typing_TypeAlias = ast.Expression | ast.IfExp | ast.Lambda
|
|
24
|
+
astClassHasDOTbody: typing_TypeAlias = astClassHasDOTbody_expr | astClassHasDOTbodyList_stmt
|
|
25
|
+
|
|
26
|
+
astClassHasDOTnameNotNameOptionally: typing_TypeAlias = ast.ExceptHandler | ast.MatchAs | ast.MatchStar
|
|
27
|
+
astClassHasDOTnameNotName: typing_TypeAlias = astClassHasDOTnameNotNameAlways | astClassHasDOTnameNotNameOptionally
|
|
28
|
+
|
|
21
29
|
astClassHasDOTtargetAttributeNameSubscript: typing_TypeAlias = ast.AnnAssign | ast.AugAssign
|
|
22
30
|
astClassHasDOTtarget_expr: typing_TypeAlias = ast.AsyncFor | ast.comprehension | ast.For
|
|
23
31
|
astClassHasDOTtarget: typing_TypeAlias = ast.NamedExpr | astClassHasDOTtarget_expr | astClassHasDOTtargetAttributeNameSubscript
|
|
24
32
|
|
|
25
|
-
astClassOptionallyHasDOTnameNotName: typing_TypeAlias = ast.ExceptHandler | ast.MatchAs | ast.MatchStar
|
|
26
|
-
|
|
27
33
|
astClassHasDOTvalue_exprNone: typing_TypeAlias = ast.AnnAssign | ast.Return | ast.Yield
|
|
28
34
|
astClassHasDOTvalue: typing_TypeAlias = ast.Constant | ast.MatchSingleton | astClassHasDOTvalue_expr | astClassHasDOTvalue_exprNone
|
|
29
35
|
|
|
@@ -73,6 +73,10 @@ class Make:
|
|
|
73
73
|
buffaloBuffalo = addDOTattribute(buffaloBuffalo, identifier, context, **keywordArguments)
|
|
74
74
|
return buffaloBuffalo
|
|
75
75
|
|
|
76
|
+
@staticmethod
|
|
77
|
+
def AugAssign(target: ast.Attribute | ast.Name | ast.Subscript, operator: ast.operator, value: ast.expr, **keywordArguments: int) -> ast.AugAssign:
|
|
78
|
+
return ast.AugAssign(target, operator, value, **keywordArguments)
|
|
79
|
+
|
|
76
80
|
@staticmethod
|
|
77
81
|
def Call(callee: ast.expr, listArguments: Sequence[ast.expr] | None = None, list_astKeywords: Sequence[ast.keyword] | None = None) -> ast.Call:
|
|
78
82
|
return ast.Call(func=callee, args=list(listArguments) if listArguments else [], keywords=list(list_astKeywords) if list_astKeywords else [])
|
|
@@ -124,3 +128,7 @@ class Make:
|
|
|
124
128
|
@staticmethod
|
|
125
129
|
def Tuple(elements: Sequence[ast.expr] = [], context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Tuple:
|
|
126
130
|
return ast.Tuple(list(elements), context, **keywordArguments)
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def While(test: ast.expr, doThis: list[ast.stmt], orElse: list[ast.stmt] = [], **keywordArguments: int) -> ast.While:
|
|
134
|
+
return ast.While(test, doThis, orElse, **keywordArguments)
|
|
@@ -16,7 +16,7 @@ once they have been identified using predicate functions from ifThis.
|
|
|
16
16
|
|
|
17
17
|
from collections.abc import Callable, Sequence
|
|
18
18
|
from mapFolding.someAssemblyRequired import ast_Identifier, astClassHasDOTvalue, ImaCallToName, NodeORattribute
|
|
19
|
-
from typing import Any
|
|
19
|
+
from typing import Any, overload
|
|
20
20
|
import ast
|
|
21
21
|
|
|
22
22
|
class grab:
|
|
@@ -32,6 +32,14 @@ class grab:
|
|
|
32
32
|
specific attribute of that node, and returns the modified node. This enables fine-grained
|
|
33
33
|
control when transforming AST structures.
|
|
34
34
|
"""
|
|
35
|
+
@staticmethod
|
|
36
|
+
def andDoAllOf(listOfActions: list[Callable[[NodeORattribute], NodeORattribute]]) -> Callable[[NodeORattribute], NodeORattribute]:
|
|
37
|
+
def workhorse(node: NodeORattribute) -> NodeORattribute:
|
|
38
|
+
for action in listOfActions:
|
|
39
|
+
node = action(node)
|
|
40
|
+
return node
|
|
41
|
+
return workhorse
|
|
42
|
+
|
|
35
43
|
@staticmethod
|
|
36
44
|
def argAttribute(action: Callable[[ast_Identifier | None], ast_Identifier]) -> Callable[[ast.arg | ast.keyword], ast.arg | ast.keyword]:
|
|
37
45
|
def workhorse(node: ast.arg | ast.keyword) -> ast.arg | ast.keyword:
|
|
@@ -39,6 +47,20 @@ class grab:
|
|
|
39
47
|
return node
|
|
40
48
|
return workhorse
|
|
41
49
|
|
|
50
|
+
@staticmethod
|
|
51
|
+
def attrAttribute(action: Callable[[ast_Identifier], ast_Identifier]) -> Callable[[ast.Attribute], ast.Attribute]:
|
|
52
|
+
def workhorse(node: ast.Attribute) -> ast.Attribute:
|
|
53
|
+
node.attr = action(node.attr)
|
|
54
|
+
return node
|
|
55
|
+
return workhorse
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def comparatorsAttribute(action: Callable[[list[ast.expr]], list[ast.expr]]) -> Callable[[ast.Compare], ast.Compare]:
|
|
59
|
+
def workhorse(node: ast.Compare) -> ast.Compare:
|
|
60
|
+
node.comparators = action(node.comparators)
|
|
61
|
+
return node
|
|
62
|
+
return workhorse
|
|
63
|
+
|
|
42
64
|
@staticmethod
|
|
43
65
|
def funcAttribute(action: Callable[[ast.expr], ast.expr]) -> Callable[[ast.Call], ast.Call]:
|
|
44
66
|
def workhorse(node: ast.Call) -> ast.Call:
|
|
@@ -60,6 +82,27 @@ class grab:
|
|
|
60
82
|
return node
|
|
61
83
|
return workhorse
|
|
62
84
|
|
|
85
|
+
@staticmethod
|
|
86
|
+
def leftAttribute(action: Callable[[ast.expr], ast.expr]) -> Callable[[ast.BinOp | ast.Compare], ast.BinOp | ast.Compare]:
|
|
87
|
+
def workhorse(node: ast.BinOp | ast.Compare) -> ast.BinOp | ast.Compare:
|
|
88
|
+
node.left = action(node.left)
|
|
89
|
+
return node
|
|
90
|
+
return workhorse
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def opsAttribute(action: Callable[[list[ast.cmpop]], list[ast.cmpop]]) -> Callable[[ast.Compare], ast.Compare]:
|
|
94
|
+
def workhorse(node: ast.Compare) -> ast.Compare:
|
|
95
|
+
node.ops = action(node.ops)
|
|
96
|
+
return node
|
|
97
|
+
return workhorse
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
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]:
|
|
101
|
+
def workhorse(node: ast.Assert | ast.If | ast.IfExp | ast.While) -> ast.Assert | ast.If | ast.IfExp | ast.While:
|
|
102
|
+
node.test = action(node.test)
|
|
103
|
+
return node
|
|
104
|
+
return workhorse
|
|
105
|
+
|
|
63
106
|
@staticmethod
|
|
64
107
|
def valueAttribute(action: Callable[[Any], Any]) -> Callable[[astClassHasDOTvalue], astClassHasDOTvalue]:
|
|
65
108
|
def workhorse(node: astClassHasDOTvalue) -> astClassHasDOTvalue:
|
|
@@ -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,36 +1,39 @@
|
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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,
|
|
31
|
+
astClassHasDOTtarget_expr,
|
|
27
32
|
astClassHasDOTtarget,
|
|
28
33
|
astClassHasDOTtargetAttributeNameSubscript,
|
|
29
|
-
astClassHasDOTtarget_expr,
|
|
30
|
-
astClassHasDOTvalue,
|
|
31
34
|
astClassHasDOTvalue_expr,
|
|
32
|
-
astClassOptionallyHasDOTnameNotName,
|
|
33
35
|
astClassHasDOTvalue_exprNone,
|
|
36
|
+
astClassHasDOTvalue,
|
|
34
37
|
ImaCallToName,
|
|
35
38
|
)
|
|
36
39
|
from typing import Any, overload, TypeGuard
|
|
@@ -72,6 +75,16 @@ class DOT:
|
|
|
72
75
|
def attr(node: ast.Attribute) -> ast_Identifier:
|
|
73
76
|
return node.attr
|
|
74
77
|
|
|
78
|
+
@staticmethod
|
|
79
|
+
@overload
|
|
80
|
+
def body(node: astClassHasDOTbodyList_stmt) -> list[ast.stmt]:...
|
|
81
|
+
@staticmethod
|
|
82
|
+
@overload
|
|
83
|
+
def body(node: astClassHasDOTbody_expr) -> ast.expr:...
|
|
84
|
+
@staticmethod
|
|
85
|
+
def body(node: astClassHasDOTbody) -> ast.expr | list[ast.stmt]:
|
|
86
|
+
return node.body
|
|
87
|
+
|
|
75
88
|
@staticmethod
|
|
76
89
|
@overload
|
|
77
90
|
def func(node: ImaCallToName) -> ast.Name:...
|
|
@@ -88,12 +101,12 @@ class DOT:
|
|
|
88
101
|
|
|
89
102
|
@staticmethod
|
|
90
103
|
@overload
|
|
91
|
-
def name(node:
|
|
104
|
+
def name(node: astClassHasDOTnameNotNameAlways) -> ast_Identifier:...
|
|
92
105
|
@staticmethod
|
|
93
106
|
@overload
|
|
94
|
-
def name(node:
|
|
107
|
+
def name(node: astClassHasDOTnameNotNameOptionally) -> ast_Identifier | None:...
|
|
95
108
|
@staticmethod
|
|
96
|
-
def name(node: astClassHasDOTnameNotName
|
|
109
|
+
def name(node: astClassHasDOTnameNotName) -> ast_Identifier | None:
|
|
97
110
|
return node.name
|
|
98
111
|
|
|
99
112
|
@staticmethod
|
|
@@ -129,18 +142,16 @@ class be:
|
|
|
129
142
|
"""
|
|
130
143
|
Provide type-guard functions for safely verifying AST node types during manipulation.
|
|
131
144
|
|
|
132
|
-
The be class contains static methods that perform runtime type verification of AST nodes,
|
|
133
|
-
|
|
134
|
-
conditional branches. These type-guards:
|
|
145
|
+
The be class contains static methods that perform runtime type verification of AST nodes, returning TypeGuard
|
|
146
|
+
results that enable static type checkers to narrow node types in conditional branches. These type-guards:
|
|
135
147
|
|
|
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
|
|
148
|
+
1. Improve code safety by preventing operations on incompatible node types.
|
|
149
|
+
2. Enable IDE tooling to provide better autocompletion and error detection.
|
|
150
|
+
3. Document expected node types in a way that's enforced by the type system.
|
|
151
|
+
4. Support pattern-matching workflows where node types must be verified before access.
|
|
140
152
|
|
|
141
|
-
When used with conditional statements, these type-guards allow for precise,
|
|
142
|
-
|
|
143
|
-
capabilities, even in complex transformation scenarios.
|
|
153
|
+
When used with conditional statements, these type-guards allow for precise, type-safe manipulation of AST nodes
|
|
154
|
+
while maintaining full static type checking capabilities, even in complex transformation scenarios.
|
|
144
155
|
"""
|
|
145
156
|
@staticmethod
|
|
146
157
|
def AnnAssign(node: ast.AST) -> TypeGuard[ast.AnnAssign]:
|
|
@@ -170,6 +181,14 @@ class be:
|
|
|
170
181
|
def ClassDef(node: ast.AST) -> TypeGuard[ast.ClassDef]:
|
|
171
182
|
return isinstance(node, ast.ClassDef)
|
|
172
183
|
|
|
184
|
+
@staticmethod
|
|
185
|
+
def Compare(node: ast.AST) -> TypeGuard[ast.Compare]:
|
|
186
|
+
return isinstance(node, ast.Compare)
|
|
187
|
+
|
|
188
|
+
@staticmethod
|
|
189
|
+
def Constant(node: ast.AST) -> TypeGuard[ast.Constant]:
|
|
190
|
+
return isinstance(node, ast.Constant)
|
|
191
|
+
|
|
173
192
|
@staticmethod
|
|
174
193
|
def FunctionDef(node: ast.AST) -> TypeGuard[ast.FunctionDef]:
|
|
175
194
|
return isinstance(node, ast.FunctionDef)
|
|
@@ -178,6 +197,18 @@ class be:
|
|
|
178
197
|
def keyword(node: ast.AST) -> TypeGuard[ast.keyword]:
|
|
179
198
|
return isinstance(node, ast.keyword)
|
|
180
199
|
|
|
200
|
+
@staticmethod
|
|
201
|
+
def If(node: ast.AST) -> TypeGuard[ast.If]:
|
|
202
|
+
return isinstance(node, ast.If)
|
|
203
|
+
|
|
204
|
+
@staticmethod
|
|
205
|
+
def Gt(node: ast.AST) -> TypeGuard[ast.Gt]:
|
|
206
|
+
return isinstance(node, ast.Gt)
|
|
207
|
+
|
|
208
|
+
@staticmethod
|
|
209
|
+
def LtE(node: ast.AST) -> TypeGuard[ast.LtE]:
|
|
210
|
+
return isinstance(node, ast.LtE)
|
|
211
|
+
|
|
181
212
|
@staticmethod
|
|
182
213
|
def Name(node: ast.AST) -> TypeGuard[ast.Name]:
|
|
183
214
|
return isinstance(node, ast.Name)
|
|
@@ -194,6 +225,14 @@ class be:
|
|
|
194
225
|
def Subscript(node: ast.AST) -> TypeGuard[ast.Subscript]:
|
|
195
226
|
return isinstance(node, ast.Subscript)
|
|
196
227
|
|
|
228
|
+
@staticmethod
|
|
229
|
+
def Tuple(node: ast.AST) -> TypeGuard[ast.Tuple]:
|
|
230
|
+
return isinstance(node, ast.Tuple)
|
|
231
|
+
|
|
232
|
+
@staticmethod
|
|
233
|
+
def While(node: ast.AST) -> TypeGuard[ast.While]:
|
|
234
|
+
return isinstance(node, ast.While)
|
|
235
|
+
|
|
197
236
|
class ifThis:
|
|
198
237
|
"""
|
|
199
238
|
Provide predicate functions for matching and filtering AST nodes based on various criteria.
|
|
@@ -257,6 +296,29 @@ class ifThis:
|
|
|
257
296
|
def isAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
|
|
258
297
|
return lambda node: ifThis.isAttributeName(node) and ifThis.isName_Identifier(namespace)(DOT.value(node)) and ifThis._Identifier(identifier)(DOT.attr(node))
|
|
259
298
|
|
|
299
|
+
@staticmethod
|
|
300
|
+
def isAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
|
|
301
|
+
return lambda node: (be.Compare(node)
|
|
302
|
+
and ifThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
|
|
303
|
+
and be.Gt(node.ops[0])
|
|
304
|
+
and ifThis.isConstant_value(0)(node.comparators[0]))
|
|
305
|
+
|
|
306
|
+
@staticmethod
|
|
307
|
+
def isIfAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.While] | bool]:
|
|
308
|
+
return lambda node: (be.If(node)
|
|
309
|
+
and ifThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
|
|
310
|
+
|
|
311
|
+
@staticmethod
|
|
312
|
+
def isWhileAttributeNamespace_IdentifierGreaterThan0(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.While] | bool]:
|
|
313
|
+
return lambda node: (be.While(node)
|
|
314
|
+
and ifThis.isAttributeNamespace_IdentifierGreaterThan0(namespace, identifier)(node.test))
|
|
315
|
+
|
|
316
|
+
@staticmethod
|
|
317
|
+
def isAttributeNamespace_IdentifierLessThanOrEqual(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Compare] | bool]:
|
|
318
|
+
return lambda node: (be.Compare(node)
|
|
319
|
+
and ifThis.isAttributeNamespace_Identifier(namespace, identifier)(node.left)
|
|
320
|
+
and be.LtE(node.ops[0]))
|
|
321
|
+
|
|
260
322
|
@staticmethod
|
|
261
323
|
def isAugAssign_targetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AugAssign] | bool]:
|
|
262
324
|
def workhorse(node: ast.AST) -> TypeGuard[ast.AugAssign] | bool:
|
|
@@ -282,6 +344,10 @@ class ifThis:
|
|
|
282
344
|
def isClassDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.ClassDef] | bool]:
|
|
283
345
|
return lambda node: be.ClassDef(node) and ifThis._Identifier(identifier)(DOT.name(node))
|
|
284
346
|
|
|
347
|
+
@staticmethod
|
|
348
|
+
def isConstant_value(value: Any) -> Callable[[ast.AST], TypeGuard[ast.Constant] | bool]:
|
|
349
|
+
return lambda node: be.Constant(node) and DOT.value(node) == value
|
|
350
|
+
|
|
285
351
|
@staticmethod
|
|
286
352
|
def isFunctionDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.FunctionDef] | bool]:
|
|
287
353
|
return lambda node: be.FunctionDef(node) and ifThis._Identifier(identifier)(DOT.name(node))
|