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,20 +1,24 @@
|
|
|
1
|
-
"""It's still wrong, but typing information is being transmitted between functions, methods, and modules."""
|
|
2
1
|
from typing import Any, TYPE_CHECKING, TypeAlias as typing_TypeAlias, TypeVar as typing_TypeVar
|
|
3
2
|
import ast
|
|
3
|
+
# TODO understand typing.
|
|
4
4
|
|
|
5
5
|
stuPyd: typing_TypeAlias = str
|
|
6
|
-
|
|
7
6
|
if TYPE_CHECKING:
|
|
8
7
|
""" 3.12 new: ast.ParamSpec, ast.type_param, ast.TypeAlias, ast.TypeVar, ast.TypeVarTuple
|
|
9
8
|
3.11 new: ast.TryStar"""
|
|
10
9
|
astClassHasDOTnameNotName: typing_TypeAlias = ast.alias | ast.AsyncFunctionDef | ast.ClassDef | ast.FunctionDef | ast.ParamSpec | ast.TypeVar | ast.TypeVarTuple
|
|
11
|
-
|
|
10
|
+
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
|
else:
|
|
13
13
|
astClassHasDOTnameNotName = stuPyd
|
|
14
|
-
|
|
14
|
+
astClassHasDOTvalue_expr = stuPyd
|
|
15
15
|
|
|
16
|
+
astClassHasDOTtargetAttributeNameSubscript: typing_TypeAlias = ast.AnnAssign | ast.AugAssign
|
|
17
|
+
astClassHasDOTtarget_expr: typing_TypeAlias = ast.AsyncFor | ast.comprehension | ast.For
|
|
18
|
+
astClassHasDOTtarget: typing_TypeAlias = ast.NamedExpr | astClassHasDOTtarget_expr | astClassHasDOTtargetAttributeNameSubscript
|
|
16
19
|
astClassOptionallyHasDOTnameNotName: typing_TypeAlias = ast.ExceptHandler | ast.MatchAs | ast.MatchStar
|
|
17
|
-
|
|
20
|
+
astClassHasDOTvalue_exprNone: typing_TypeAlias = ast.AnnAssign | ast.Return | ast.Yield
|
|
21
|
+
astClassHasDOTvalue: typing_TypeAlias = ast.Constant | ast.MatchSingleton | astClassHasDOTvalue_expr | astClassHasDOTvalue_exprNone
|
|
18
22
|
|
|
19
23
|
ast_expr_Slice: typing_TypeAlias = ast.expr
|
|
20
24
|
ast_Identifier: typing_TypeAlias = str
|
|
@@ -22,18 +26,10 @@ intORlist_ast_type_paramORstr_orNone: typing_TypeAlias = Any
|
|
|
22
26
|
intORstr_orNone: typing_TypeAlias = Any
|
|
23
27
|
list_ast_type_paramORstr_orNone: typing_TypeAlias = Any
|
|
24
28
|
str_nameDOTname: typing_TypeAlias = stuPyd
|
|
25
|
-
ImaAnnotationType: typing_TypeAlias = ast.Attribute | ast.Constant | ast.Name | ast.Subscript
|
|
26
|
-
ImaAnnotationTypeVar = typing_TypeVar('ImaAnnotationTypeVar', ast.Attribute, ast.Constant, ast.Name, ast.Subscript)
|
|
27
|
-
|
|
28
|
-
Ima_funcTypeUNEDITED: typing_TypeAlias = ast.Attribute | ast.Await | ast.BinOp | ast.BoolOp | ast.Call | ast.Compare | ast.Constant | ast.Dict | ast.DictComp | ast.FormattedValue | ast.GeneratorExp | ast.IfExp | ast.JoinedStr | ast.Lambda | ast.List | ast.ListComp | ast.Name | ast.NamedExpr | ast.Set | ast.SetComp | ast.Slice | ast.Starred | ast.Subscript | ast.Tuple | ast.UnaryOp | ast.Yield | ast.YieldFrom
|
|
29
|
-
Ima_targetTypeUNEDITED: typing_TypeAlias = ast.AST
|
|
30
|
-
|
|
31
|
-
# TODO understand whatever the fuck `typing.TypeVar` is _supposed_ to fucking do.
|
|
32
|
-
TypeCertified = typing_TypeVar('TypeCertified', bound = ast.AST, covariant=True)
|
|
33
|
-
astMosDef = typing_TypeVar('astMosDef', bound=astClassHasDOTnameNotName)
|
|
34
29
|
|
|
35
|
-
个 = typing_TypeVar('个', bound= ast.AST
|
|
30
|
+
个 = typing_TypeVar('个', bound= ast.AST, covariant=True)
|
|
36
31
|
|
|
32
|
+
# All ast classes by subgroup:
|
|
37
33
|
Ima_ast_boolop: typing_TypeAlias = ast.boolop | ast.And | ast.Or
|
|
38
34
|
Ima_ast_cmpop: typing_TypeAlias = ast.cmpop | ast.Eq | ast.NotEq | ast.Lt | ast.LtE | ast.Gt | ast.GtE | ast.Is | ast.IsNot | ast.In | ast.NotIn
|
|
39
35
|
Ima_ast_excepthandler: typing_TypeAlias = ast.excepthandler | ast.ExceptHandler
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AST Node Construction Utilities for Python Code Generation
|
|
3
|
+
|
|
4
|
+
This module provides the Make class with static methods for creating AST nodes
|
|
5
|
+
with sane defaults. It abstracts away the complexity of constructing AST nodes
|
|
6
|
+
directly, making programmatic code generation more intuitive and less error-prone.
|
|
7
|
+
|
|
8
|
+
The Make class serves as a factory for creating various types of AST nodes needed
|
|
9
|
+
in code generation, transformation, and analysis workflows. Each method follows
|
|
10
|
+
a consistent pattern that maps cleanly to Python's syntax while handling the
|
|
11
|
+
details of AST node construction.
|
|
12
|
+
"""
|
|
13
|
+
|
|
1
14
|
from collections.abc import Sequence
|
|
2
15
|
from mapFolding.someAssemblyRequired import (
|
|
3
16
|
ast_expr_Slice,
|
|
4
17
|
ast_Identifier,
|
|
5
|
-
ImaAnnotationType,
|
|
6
18
|
intORlist_ast_type_paramORstr_orNone,
|
|
7
19
|
intORstr_orNone,
|
|
8
20
|
list_ast_type_paramORstr_orNone,
|
|
@@ -30,71 +42,86 @@ class Make:
|
|
|
30
42
|
@staticmethod
|
|
31
43
|
def alias(name: ast_Identifier, asname: ast_Identifier | None = None) -> ast.alias:
|
|
32
44
|
return ast.alias(name, asname)
|
|
45
|
+
|
|
33
46
|
@staticmethod
|
|
34
|
-
def AnnAssign(target: ast.Attribute | ast.Name | ast.Subscript, annotation:
|
|
47
|
+
def AnnAssign(target: ast.Attribute | ast.Name | ast.Subscript, annotation: ast.expr, value: ast.expr | None = None, **keywordArguments: int) -> ast.AnnAssign: # `simple: int`: uses a clever int-from-boolean to assign the correct value to the `simple` attribute. So, don't make it a method parameter.
|
|
35
48
|
return ast.AnnAssign(target, annotation, value, simple=int(isinstance(target, ast.Name)), **keywordArguments)
|
|
49
|
+
|
|
36
50
|
@staticmethod
|
|
37
51
|
def arg(identifier: ast_Identifier, annotation: ast.expr | None = None, **keywordArguments: intORstr_orNone) -> ast.arg:
|
|
38
52
|
return ast.arg(identifier, annotation, **keywordArguments)
|
|
53
|
+
|
|
39
54
|
@staticmethod
|
|
40
55
|
def argumentsSpecification(posonlyargs:list[ast.arg]=[], args:list[ast.arg]=[], vararg:ast.arg|None=None, kwonlyargs:list[ast.arg]=[], kw_defaults:list[ast.expr|None]=[None], kwarg:ast.arg|None=None, defaults:list[ast.expr]=[]) -> ast.arguments:
|
|
41
56
|
return ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults)
|
|
57
|
+
|
|
42
58
|
@staticmethod
|
|
43
|
-
def Assign(listTargets:
|
|
59
|
+
def Assign(listTargets: list[ast.expr], value: ast.expr, **keywordArguments: intORstr_orNone) -> ast.Assign:
|
|
44
60
|
return ast.Assign(listTargets, value, **keywordArguments)
|
|
61
|
+
|
|
45
62
|
@staticmethod
|
|
46
63
|
def Attribute(value: ast.expr, *attribute: ast_Identifier, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Attribute:
|
|
47
64
|
""" If two `ast_Identifier` are joined by a dot `.`, they are _usually_ an `ast.Attribute`, but see `ast.ImportFrom`.
|
|
48
65
|
Parameters:
|
|
49
|
-
value: the part before the dot (
|
|
66
|
+
value: the part before the dot (e.g., `ast.Name`.)
|
|
50
67
|
attribute: an `ast_Identifier` after a dot `.`; you can pass multiple `attribute` and they will be chained together.
|
|
51
68
|
"""
|
|
52
|
-
|
|
53
|
-
def addDOTattribute(chain, identifier: ast_Identifier, context: ast.expr_context, **keywordArguments: int) -> ast.Attribute:
|
|
69
|
+
def addDOTattribute(chain: ast.expr, identifier: ast_Identifier, context: ast.expr_context, **keywordArguments: int) -> ast.Attribute:
|
|
54
70
|
return ast.Attribute(value=chain, attr=identifier, ctx=context, **keywordArguments)
|
|
55
71
|
buffaloBuffalo = addDOTattribute(value, attribute[0], context, **keywordArguments)
|
|
56
72
|
for identifier in attribute[1:None]:
|
|
57
73
|
buffaloBuffalo = addDOTattribute(buffaloBuffalo, identifier, context, **keywordArguments)
|
|
58
74
|
return buffaloBuffalo
|
|
75
|
+
|
|
59
76
|
@staticmethod
|
|
60
|
-
|
|
61
|
-
# TODO is there an easier way to create precise typings for `ast`? I mean, it's a fucking closed system: there should be a lot of mystery involved.
|
|
62
|
-
def Call(callee: ast.Attribute | ast.Name | ast.Subscript, listArguments: Sequence[ast.expr] | None = None, list_astKeywords: Sequence[ast.keyword] | None = None) -> ast.Call:
|
|
77
|
+
def Call(callee: ast.expr, listArguments: Sequence[ast.expr] | None = None, list_astKeywords: Sequence[ast.keyword] | None = None) -> ast.Call:
|
|
63
78
|
return ast.Call(func=callee, args=list(listArguments) if listArguments else [], keywords=list(list_astKeywords) if list_astKeywords else [])
|
|
79
|
+
|
|
64
80
|
@staticmethod
|
|
65
81
|
def ClassDef(name: ast_Identifier, listBases: list[ast.expr]=[], list_keyword: list[ast.keyword]=[], body: list[ast.stmt]=[], decorator_list: list[ast.expr]=[], **keywordArguments: list_ast_type_paramORstr_orNone) -> ast.ClassDef:
|
|
66
82
|
return ast.ClassDef(name, listBases, list_keyword, body, decorator_list, **keywordArguments)
|
|
83
|
+
|
|
67
84
|
@staticmethod
|
|
68
85
|
def Constant(value: Any, **keywordArguments: intORstr_orNone) -> ast.Constant:
|
|
69
86
|
"""value: str|int|float|bool|None|bytes|bytearray|memoryview|complex|list|tuple|dict|set, or any other type that can be represented as a constant in Python."""
|
|
70
87
|
return ast.Constant(value, **keywordArguments)
|
|
88
|
+
|
|
71
89
|
@staticmethod
|
|
72
90
|
def Expr(value: ast.expr, **keywordArguments: int) -> ast.Expr:
|
|
73
91
|
return ast.Expr(value, **keywordArguments)
|
|
92
|
+
|
|
74
93
|
@staticmethod
|
|
75
94
|
def FunctionDef(name: ast_Identifier, argumentsSpecification:ast.arguments=ast.arguments(), body:list[ast.stmt]=[], decorator_list:list[ast.expr]=[], returns:ast.expr|None=None, **keywordArguments: intORlist_ast_type_paramORstr_orNone) -> ast.FunctionDef:
|
|
76
95
|
return ast.FunctionDef(name, argumentsSpecification, body, decorator_list, returns, **keywordArguments)
|
|
96
|
+
|
|
77
97
|
@staticmethod
|
|
78
98
|
def Import(moduleWithLogicalPath: str_nameDOTname, asname: ast_Identifier | None = None, **keywordArguments: int) -> ast.Import:
|
|
79
99
|
return ast.Import(names=[Make.alias(moduleWithLogicalPath, asname)], **keywordArguments)
|
|
100
|
+
|
|
80
101
|
@staticmethod
|
|
81
102
|
def ImportFrom(moduleWithLogicalPath: str_nameDOTname, list_astAlias: list[ast.alias], **keywordArguments: int) -> ast.ImportFrom:
|
|
82
103
|
return ast.ImportFrom(moduleWithLogicalPath, list_astAlias, **keywordArguments)
|
|
104
|
+
|
|
83
105
|
@staticmethod
|
|
84
106
|
def keyword(keywordArgument: ast_Identifier, value: ast.expr, **keywordArguments: int) -> ast.keyword:
|
|
85
107
|
return ast.keyword(arg=keywordArgument, value=value, **keywordArguments)
|
|
108
|
+
|
|
86
109
|
@staticmethod
|
|
87
110
|
def Module(body: list[ast.stmt] = [], type_ignores: list[ast.TypeIgnore] = []) -> ast.Module:
|
|
88
111
|
return ast.Module(body, type_ignores)
|
|
112
|
+
|
|
89
113
|
@staticmethod
|
|
90
114
|
def Name(identifier: ast_Identifier, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Name:
|
|
91
115
|
return ast.Name(identifier, context, **keywordArguments)
|
|
116
|
+
|
|
92
117
|
@staticmethod
|
|
93
118
|
def Return(value: ast.expr | None = None, **keywordArguments: int) -> ast.Return:
|
|
94
119
|
return ast.Return(value, **keywordArguments)
|
|
120
|
+
|
|
95
121
|
@staticmethod
|
|
96
122
|
def Subscript(value: ast.expr, slice: ast_expr_Slice, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Subscript:
|
|
97
123
|
return ast.Subscript(value, slice, context, **keywordArguments)
|
|
124
|
+
|
|
98
125
|
@staticmethod
|
|
99
126
|
def Tuple(elements: Sequence[ast.expr] = [], context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Tuple:
|
|
100
127
|
return ast.Tuple(list(elements), context, **keywordArguments)
|
|
@@ -1,67 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AST Node Transformation Actions for Python Code Manipulation
|
|
3
|
+
|
|
4
|
+
This module provides the Then class with static methods for generating callable
|
|
5
|
+
action functions that specify what to do with AST nodes that match predicates.
|
|
6
|
+
These action functions are used primarily with NodeChanger and NodeTourist to
|
|
7
|
+
transform or extract information from AST nodes.
|
|
8
|
+
|
|
9
|
+
The module also contains the grab class that provides functions for modifying
|
|
10
|
+
specific attributes of AST nodes while preserving their structure, enabling
|
|
11
|
+
fine-grained control when transforming AST structures.
|
|
12
|
+
|
|
13
|
+
Together, these classes provide a complete system for manipulating AST nodes
|
|
14
|
+
once they have been identified using predicate functions from ifThis.
|
|
15
|
+
"""
|
|
16
|
+
|
|
1
17
|
from collections.abc import Callable, Sequence
|
|
2
18
|
from mapFolding.someAssemblyRequired import ast_Identifier, astClassHasDOTvalue
|
|
3
19
|
from typing import Any
|
|
4
20
|
import ast
|
|
5
21
|
|
|
6
|
-
class
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def workhorse(node: ast.AST) -> ast.AST:
|
|
10
|
-
for action in listActions: action(node)
|
|
11
|
-
return node
|
|
12
|
-
return workhorse
|
|
22
|
+
class grab:
|
|
23
|
+
"""
|
|
24
|
+
Modify specific attributes of AST nodes while preserving the node structure.
|
|
13
25
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return listOfAny
|
|
19
|
-
return workhorse
|
|
26
|
+
The grab class provides static methods that create transformation functions to modify
|
|
27
|
+
specific attributes of AST nodes. Unlike DOT which provides read-only access,
|
|
28
|
+
grab allows for targeted modifications of node attributes without replacing the
|
|
29
|
+
entire node.
|
|
20
30
|
|
|
31
|
+
Each method returns a function that takes a node, applies a transformation to a
|
|
32
|
+
specific attribute of that node, and returns the modified node. This enables fine-grained
|
|
33
|
+
control when transforming AST structures.
|
|
34
|
+
"""
|
|
21
35
|
@staticmethod
|
|
22
|
-
def
|
|
36
|
+
def argAttribute(action: Callable[[ast_Identifier | None], ast_Identifier]) -> Callable[[ast.arg | ast.keyword], ast.arg | ast.keyword]:
|
|
23
37
|
def workhorse(node: ast.arg | ast.keyword) -> ast.arg | ast.keyword:
|
|
24
38
|
node.arg = action(node.arg)
|
|
25
39
|
return node
|
|
26
40
|
return workhorse
|
|
41
|
+
|
|
27
42
|
@staticmethod
|
|
28
|
-
def
|
|
43
|
+
def funcAttribute(action: Callable[[ast.expr], ast.expr]) -> Callable[[ast.Call], ast.Call]:
|
|
29
44
|
def workhorse(node: ast.Call) -> ast.Call:
|
|
30
45
|
node.func = action(node.func)
|
|
31
46
|
return node
|
|
32
47
|
return workhorse
|
|
48
|
+
|
|
33
49
|
@staticmethod
|
|
34
|
-
def
|
|
50
|
+
def idAttribute(action: Callable[[ast_Identifier], ast_Identifier]) -> Callable[[ast.Name], ast.Name]:
|
|
35
51
|
def workhorse(node: ast.Name) -> ast.Name:
|
|
36
52
|
node.id = action(node.id)
|
|
37
53
|
return node
|
|
38
54
|
return workhorse
|
|
55
|
+
|
|
39
56
|
@staticmethod
|
|
40
|
-
def
|
|
41
|
-
def workhorse(node: ast.AnnAssign | ast.AugAssign) -> ast.AnnAssign | ast.AugAssign:
|
|
42
|
-
node.target = action(node.target)
|
|
43
|
-
return node
|
|
44
|
-
return workhorse
|
|
45
|
-
@staticmethod
|
|
46
|
-
def DOTvalue(action: Callable[[Any], Any]) -> Callable[[astClassHasDOTvalue], astClassHasDOTvalue]:
|
|
57
|
+
def valueAttribute(action: Callable[[Any | ast.expr | bool | None], Any]) -> Callable[[astClassHasDOTvalue], astClassHasDOTvalue]:
|
|
47
58
|
def workhorse(node: astClassHasDOTvalue) -> astClassHasDOTvalue:
|
|
48
59
|
node.value = action(node.value)
|
|
49
60
|
return node
|
|
50
61
|
return workhorse
|
|
51
62
|
|
|
63
|
+
class Then:
|
|
64
|
+
"""
|
|
65
|
+
Provide action functions that specify what to do with AST nodes that match predicates.
|
|
66
|
+
|
|
67
|
+
The Then class contains static methods that generate action functions used with
|
|
68
|
+
NodeChanger and NodeTourist to transform or extract information from AST nodes
|
|
69
|
+
that match specific predicates. These actions include node replacement, insertion,
|
|
70
|
+
extraction, and collection operations.
|
|
71
|
+
|
|
72
|
+
When paired with predicates from the ifThis class, Then methods complete the
|
|
73
|
+
pattern-matching-and-action workflow for AST manipulation.
|
|
74
|
+
"""
|
|
52
75
|
@staticmethod
|
|
53
|
-
def
|
|
76
|
+
def appendTo(listOfAny: list[Any]) -> Callable[[ast.AST | ast_Identifier], list[Any]]:
|
|
77
|
+
def workhorse(node: ast.AST | ast_Identifier) -> list[Any]:
|
|
78
|
+
listOfAny.append(node)
|
|
79
|
+
return listOfAny
|
|
80
|
+
return workhorse
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def extractIt(node: ast.AST) -> ast.AST | ast_Identifier:
|
|
54
84
|
return node
|
|
85
|
+
|
|
55
86
|
@staticmethod
|
|
56
87
|
def insertThisAbove(list_astAST: Sequence[ast.AST]) -> Callable[[ast.AST], Sequence[ast.AST]]:
|
|
57
88
|
return lambda aboveMe: [*list_astAST, aboveMe]
|
|
89
|
+
|
|
58
90
|
@staticmethod
|
|
59
91
|
def insertThisBelow(list_astAST: Sequence[ast.AST]) -> Callable[[ast.AST], Sequence[ast.AST]]:
|
|
60
92
|
return lambda belowMe: [belowMe, *list_astAST]
|
|
93
|
+
|
|
61
94
|
@staticmethod
|
|
62
95
|
def removeIt(_node: ast.AST) -> None: return None
|
|
96
|
+
|
|
63
97
|
@staticmethod
|
|
64
|
-
def replaceWith(astAST:
|
|
98
|
+
def replaceWith(astAST: Any) -> Callable[[Any], Any]:
|
|
65
99
|
return lambda _replaceMe: astAST
|
|
66
100
|
|
|
67
101
|
@staticmethod
|