mapFolding 0.8.3__py3-none-any.whl → 0.8.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mapFolding/__init__.py +6 -3
- mapFolding/basecamp.py +13 -7
- mapFolding/beDRY.py +241 -68
- mapFolding/oeis.py +4 -4
- mapFolding/reference/hunterNumba.py +1 -1
- mapFolding/someAssemblyRequired/__init__.py +40 -20
- mapFolding/someAssemblyRequired/_theTypes.py +53 -0
- mapFolding/someAssemblyRequired/_tool_Make.py +99 -0
- mapFolding/someAssemblyRequired/_tool_Then.py +72 -0
- mapFolding/someAssemblyRequired/_toolboxAntecedents.py +358 -0
- mapFolding/someAssemblyRequired/_toolboxContainers.py +334 -0
- mapFolding/someAssemblyRequired/_toolboxPython.py +62 -0
- mapFolding/someAssemblyRequired/getLLVMforNoReason.py +2 -2
- mapFolding/someAssemblyRequired/newInliner.py +22 -0
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +158 -0
- mapFolding/someAssemblyRequired/toolboxNumba.py +358 -0
- mapFolding/someAssemblyRequired/transformationTools.py +289 -698
- mapFolding/syntheticModules/numbaCount_doTheNeedful.py +36 -33
- mapFolding/theDao.py +13 -11
- mapFolding/theSSOT.py +83 -128
- mapFolding/toolboxFilesystem.py +219 -0
- {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/METADATA +4 -2
- mapfolding-0.8.5.dist-info/RECORD +48 -0
- {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/WHEEL +1 -1
- tests/conftest.py +56 -52
- tests/test_computations.py +42 -32
- tests/test_filesystem.py +4 -4
- tests/test_other.py +2 -2
- tests/test_tasks.py +2 -2
- mapFolding/filesystem.py +0 -129
- mapFolding/someAssemblyRequired/ingredientsNumba.py +0 -206
- mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +0 -211
- mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py +0 -413
- mapFolding/someAssemblyRequired/transformDataStructures.py +0 -168
- mapfolding-0.8.3.dist-info/RECORD +0 -43
- {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.8.3.dist-info → mapfolding-0.8.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from collections.abc import Sequence
|
|
2
|
+
from mapFolding.someAssemblyRequired import (
|
|
3
|
+
ast_expr_Slice,
|
|
4
|
+
ast_Identifier,
|
|
5
|
+
ImaAnnotationType,
|
|
6
|
+
intORlist_ast_type_paramORstr_orNone,
|
|
7
|
+
intORstr_orNone,
|
|
8
|
+
list_ast_type_paramORstr_orNone,
|
|
9
|
+
)
|
|
10
|
+
from typing import Any
|
|
11
|
+
import ast
|
|
12
|
+
|
|
13
|
+
class Make:
|
|
14
|
+
"""Almost all parameters described here are only accessible through a method's `**keywordArguments` parameter.
|
|
15
|
+
|
|
16
|
+
Parameters:
|
|
17
|
+
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()`.
|
|
18
|
+
col_offset (0): int Position information specifying the column where an AST node begins.
|
|
19
|
+
end_col_offset (None): int|None Position information specifying the column where an AST node ends.
|
|
20
|
+
end_lineno (None): int|None Position information specifying the line number where an AST node ends.
|
|
21
|
+
level (0): int Module import depth level that controls relative vs absolute imports. Default 0 indicates absolute import.
|
|
22
|
+
lineno: int Position information manually specifying the line number where an AST node begins.
|
|
23
|
+
kind (None): str|None Used for type annotations in limited cases.
|
|
24
|
+
type_comment (None): str|None "type_comment is an optional string with the type annotation as a comment." or `# type: ignore`.
|
|
25
|
+
type_params: list[ast.type_param] Type parameters for generic type definitions.
|
|
26
|
+
|
|
27
|
+
The `ast._Attributes`, lineno, col_offset, end_lineno, and end_col_offset, hold position information; however, they are, importantly, _not_ `ast._fields`.
|
|
28
|
+
"""
|
|
29
|
+
@staticmethod
|
|
30
|
+
def alias(name: ast_Identifier, asname: ast_Identifier | None = None) -> ast.alias:
|
|
31
|
+
return ast.alias(name, asname)
|
|
32
|
+
@staticmethod
|
|
33
|
+
def AnnAssign(target: ast.Attribute | ast.Name | ast.Subscript, annotation: ImaAnnotationType, 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.
|
|
34
|
+
return ast.AnnAssign(target, annotation, value, simple=int(isinstance(target, ast.Name)), **keywordArguments)
|
|
35
|
+
@staticmethod
|
|
36
|
+
def arg(identifier: ast_Identifier, annotation: ast.expr | None = None, **keywordArguments: intORstr_orNone) -> ast.arg:
|
|
37
|
+
return ast.arg(identifier, annotation, **keywordArguments)
|
|
38
|
+
@staticmethod
|
|
39
|
+
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:
|
|
40
|
+
return ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults)
|
|
41
|
+
@staticmethod
|
|
42
|
+
def Assign(listTargets: Any, value: ast.expr, **keywordArguments: intORstr_orNone) -> ast.Assign:
|
|
43
|
+
return ast.Assign(listTargets, value, **keywordArguments)
|
|
44
|
+
@staticmethod
|
|
45
|
+
def Attribute(value: ast.expr, *attribute: ast_Identifier, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Attribute:
|
|
46
|
+
""" If two `ast_Identifier` are joined by a dot `.`, they are _usually_ an `ast.Attribute`, but see `ast.ImportFrom`.
|
|
47
|
+
Parameters:
|
|
48
|
+
value: the part before the dot (Often `ast.Name`, but also `ast.Attribute`, `ast.Starred`, and `ast.Subscript`.)
|
|
49
|
+
attribute: an `ast_Identifier` after a dot `.`; you can pass multiple `attribute` and they will be chained together.
|
|
50
|
+
"""
|
|
51
|
+
# TODO confirm the precision of the docstring.
|
|
52
|
+
def addDOTattribute(chain, identifier: ast_Identifier, context: ast.expr_context, **keywordArguments: int) -> ast.Attribute:
|
|
53
|
+
return ast.Attribute(value=chain, attr=identifier, ctx=context, **keywordArguments)
|
|
54
|
+
buffaloBuffalo = addDOTattribute(value, attribute[0], context, **keywordArguments)
|
|
55
|
+
for identifier in attribute[1:None]:
|
|
56
|
+
buffaloBuffalo = addDOTattribute(buffaloBuffalo, identifier, context, **keywordArguments)
|
|
57
|
+
return buffaloBuffalo
|
|
58
|
+
@staticmethod
|
|
59
|
+
# TODO are the types for `callee` comprehensive?
|
|
60
|
+
# 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.
|
|
61
|
+
def Call(callee: ast.Attribute | ast.Name | ast.Subscript, listArguments: Sequence[ast.expr] | None = None, list_astKeywords: Sequence[ast.keyword] | None = None) -> ast.Call:
|
|
62
|
+
return ast.Call(func=callee, args=list(listArguments) if listArguments else [], keywords=list(list_astKeywords) if list_astKeywords else [])
|
|
63
|
+
@staticmethod
|
|
64
|
+
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:
|
|
65
|
+
return ast.ClassDef(name, listBases, list_keyword, body, decorator_list, **keywordArguments)
|
|
66
|
+
@staticmethod
|
|
67
|
+
def Constant(value: Any, **keywordArguments: intORstr_orNone) -> ast.Constant:
|
|
68
|
+
"""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."""
|
|
69
|
+
return ast.Constant(value, **keywordArguments)
|
|
70
|
+
@staticmethod
|
|
71
|
+
def Expr(value: ast.expr, **keywordArguments: int) -> ast.Expr:
|
|
72
|
+
return ast.Expr(value, **keywordArguments)
|
|
73
|
+
@staticmethod
|
|
74
|
+
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:
|
|
75
|
+
return ast.FunctionDef(name, argumentsSpecification, body, decorator_list, returns, **keywordArguments)
|
|
76
|
+
@staticmethod
|
|
77
|
+
def Import(moduleIdentifier: ast_Identifier, asname: ast_Identifier | None = None, **keywordArguments: int) -> ast.Import:
|
|
78
|
+
return ast.Import(names=[Make.alias(moduleIdentifier, asname)], **keywordArguments)
|
|
79
|
+
@staticmethod
|
|
80
|
+
def ImportFrom(moduleIdentifier: ast_Identifier, list_astAlias: list[ast.alias], **keywordArguments: int) -> ast.ImportFrom:
|
|
81
|
+
return ast.ImportFrom(moduleIdentifier, list_astAlias, **keywordArguments)
|
|
82
|
+
@staticmethod
|
|
83
|
+
def keyword(keywordArgument: ast_Identifier, value: ast.expr, **keywordArguments: int) -> ast.keyword:
|
|
84
|
+
return ast.keyword(arg=keywordArgument, value=value, **keywordArguments)
|
|
85
|
+
@staticmethod
|
|
86
|
+
def Module(body: list[ast.stmt] = [], type_ignores: list[ast.TypeIgnore] = []) -> ast.Module:
|
|
87
|
+
return ast.Module(body, type_ignores)
|
|
88
|
+
@staticmethod
|
|
89
|
+
def Name(identifier: ast_Identifier, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Name:
|
|
90
|
+
return ast.Name(identifier, context, **keywordArguments)
|
|
91
|
+
@staticmethod
|
|
92
|
+
def Return(value: ast.expr | None = None, **keywordArguments: int) -> ast.Return:
|
|
93
|
+
return ast.Return(value, **keywordArguments)
|
|
94
|
+
@staticmethod
|
|
95
|
+
def Subscript(value: ast.expr, slice: ast_expr_Slice, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Subscript:
|
|
96
|
+
return ast.Subscript(value, slice, context, **keywordArguments)
|
|
97
|
+
@staticmethod
|
|
98
|
+
def Tuple(elements: Sequence[ast.expr] = [], context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Tuple:
|
|
99
|
+
return ast.Tuple(list(elements), context, **keywordArguments)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from collections.abc import Callable, Sequence
|
|
2
|
+
from mapFolding.someAssemblyRequired import ast_Identifier, astClassHasDOTvalue
|
|
3
|
+
from typing import Any
|
|
4
|
+
import ast
|
|
5
|
+
|
|
6
|
+
class Then:
|
|
7
|
+
@staticmethod
|
|
8
|
+
def allOf(listActions: Sequence[Callable[[ast.AST], Any]]) -> Callable[[ast.AST], ast.AST]:
|
|
9
|
+
def workhorse(node: ast.AST) -> ast.AST:
|
|
10
|
+
for action in listActions: action(node)
|
|
11
|
+
return node
|
|
12
|
+
return workhorse
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def appendTo(listOfAny: list[Any]) -> Callable[[ast.AST | ast_Identifier], list[Any]]:
|
|
16
|
+
def workhorse(node: ast.AST | ast_Identifier) -> list[Any]:
|
|
17
|
+
listOfAny.append(node)
|
|
18
|
+
return listOfAny
|
|
19
|
+
return workhorse
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def DOTarg(action: Callable[[Any], Any]) -> Callable[[ast.arg | ast.keyword], ast.arg | ast.keyword]:
|
|
23
|
+
def workhorse(node: ast.arg | ast.keyword) -> ast.arg | ast.keyword:
|
|
24
|
+
node.arg = action(node.arg)
|
|
25
|
+
return node
|
|
26
|
+
return workhorse
|
|
27
|
+
@staticmethod
|
|
28
|
+
def DOTfunc(action: Callable[[Any], Any]) -> Callable[[ast.Call], ast.Call]:
|
|
29
|
+
def workhorse(node: ast.Call) -> ast.Call:
|
|
30
|
+
node.func = action(node.func)
|
|
31
|
+
return node
|
|
32
|
+
return workhorse
|
|
33
|
+
@staticmethod
|
|
34
|
+
def DOTid(action: Callable[[Any], Any]) -> Callable[[ast.Name], ast.Name]:
|
|
35
|
+
def workhorse(node: ast.Name) -> ast.Name:
|
|
36
|
+
node.id = action(node.id)
|
|
37
|
+
return node
|
|
38
|
+
return workhorse
|
|
39
|
+
@staticmethod
|
|
40
|
+
def DOTtarget(action: Callable[[Any], Any]) -> Callable[[ast.AnnAssign | ast.AugAssign], ast.AnnAssign | ast.AugAssign]:
|
|
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]:
|
|
47
|
+
def workhorse(node: astClassHasDOTvalue) -> astClassHasDOTvalue:
|
|
48
|
+
node.value = action(node.value)
|
|
49
|
+
return node
|
|
50
|
+
return workhorse
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def getIt(node: ast.AST) -> ast.AST | ast_Identifier:
|
|
54
|
+
return node
|
|
55
|
+
@staticmethod
|
|
56
|
+
def insertThisAbove(list_astAST: Sequence[ast.AST]) -> Callable[[ast.AST], Sequence[ast.AST]]:
|
|
57
|
+
return lambda aboveMe: [*list_astAST, aboveMe]
|
|
58
|
+
@staticmethod
|
|
59
|
+
def insertThisBelow(list_astAST: Sequence[ast.AST]) -> Callable[[ast.AST], Sequence[ast.AST]]:
|
|
60
|
+
return lambda belowMe: [belowMe, *list_astAST]
|
|
61
|
+
@staticmethod
|
|
62
|
+
def removeIt(_node: ast.AST) -> None: return None
|
|
63
|
+
@staticmethod
|
|
64
|
+
def replaceWith(astAST: ast.AST | ast_Identifier) -> Callable[[ast.AST], ast.AST | ast_Identifier]:
|
|
65
|
+
return lambda _replaceMe: astAST
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def updateKeyValueIn(key: Callable[..., Any], value: Callable[..., Any], dictionary: dict[Any, Any]) -> Callable[[ast.AST], dict[Any, Any]]:
|
|
69
|
+
def workhorse(node: ast.AST) -> dict[Any, Any]:
|
|
70
|
+
dictionary.setdefault(key(node), value(node))
|
|
71
|
+
return dictionary
|
|
72
|
+
return workhorse
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
from collections.abc import Callable, Container
|
|
2
|
+
from mapFolding.someAssemblyRequired import (
|
|
3
|
+
ast_expr_Slice,
|
|
4
|
+
ast_Identifier,
|
|
5
|
+
Ima_funcTypeUNEDITED,
|
|
6
|
+
astClassHasDOTnameNotName,
|
|
7
|
+
astClassOptionallyHasDOTnameNotName,
|
|
8
|
+
astClassHasDOTtarget,
|
|
9
|
+
astClassHasDOTvalue,
|
|
10
|
+
ImaAnnotationType,
|
|
11
|
+
ImaAnnotationTypeVar,
|
|
12
|
+
Ima_targetTypeUNEDITED,
|
|
13
|
+
TypeCertified,
|
|
14
|
+
)
|
|
15
|
+
from typing import Any, cast, overload, TypeGuard
|
|
16
|
+
import ast
|
|
17
|
+
|
|
18
|
+
class NotMyProblem(Exception):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
class DOT:
|
|
22
|
+
@staticmethod
|
|
23
|
+
@overload
|
|
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
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def nameOrNone(node: astClassHasDOTnameNotName | astClassOptionallyHasDOTnameNotName) -> ast_Identifier | None:
|
|
57
|
+
if isinstance(node, astClassHasDOTnameNotName):
|
|
58
|
+
return node.name
|
|
59
|
+
try:
|
|
60
|
+
return node.name
|
|
61
|
+
except AttributeError:
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
class 又:
|
|
65
|
+
@staticmethod
|
|
66
|
+
@overload
|
|
67
|
+
def annotation(predicate: Callable[[ImaAnnotationType], ast.AST | ast_Identifier]) -> Callable[[ast.AnnAssign | ast.arg], ast.AST | ast_Identifier]:...
|
|
68
|
+
@staticmethod
|
|
69
|
+
@overload
|
|
70
|
+
def annotation(predicate: Callable[[ImaAnnotationType], TypeGuard[ImaAnnotationType] | bool]) -> Callable[[ast.AnnAssign | ast.arg], TypeGuard[ast.AnnAssign] | TypeGuard[ast.arg] | bool]:...
|
|
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
|
|
84
|
+
@staticmethod
|
|
85
|
+
@overload
|
|
86
|
+
def arg(predicate: Callable[[ast_Identifier], ast.AST | ast_Identifier]) -> Callable[[ast.arg | ast.keyword], ast.AST | ast_Identifier]:...
|
|
87
|
+
@staticmethod
|
|
88
|
+
@overload
|
|
89
|
+
def arg(predicate: Callable[[ast_Identifier], TypeGuard[ast_Identifier] | bool]) -> Callable[[ast.arg | ast.keyword], TypeGuard[ast.arg] | TypeGuard[ast.keyword] | bool]:...
|
|
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)
|
|
110
|
+
@staticmethod
|
|
111
|
+
def id(predicate: Callable[[ast_Identifier], TypeGuard[ast_Identifier] | bool]) -> Callable[[ast.Name], TypeGuard[ast.Name] | bool]:
|
|
112
|
+
return lambda node: predicate(node.id)
|
|
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)
|
|
125
|
+
@staticmethod
|
|
126
|
+
def value(predicate: Callable[[ast.AST], TypeGuard[ast.AST] | bool]) -> Callable[[astClassHasDOTvalue], TypeGuard[astClassHasDOTvalue] | bool]:
|
|
127
|
+
def workhorse(node: astClassHasDOTvalue) -> TypeGuard[astClassHasDOTvalue] | bool:
|
|
128
|
+
ImaValue = node.value
|
|
129
|
+
if ImaValue is None: return False
|
|
130
|
+
return predicate(ImaValue)
|
|
131
|
+
return workhorse
|
|
132
|
+
|
|
133
|
+
class be:
|
|
134
|
+
@staticmethod
|
|
135
|
+
def _typeCertified(antecedent: type[TypeCertified]) -> Callable[[Any | None], TypeGuard[TypeCertified]]:
|
|
136
|
+
def workhorse(node: Any | None) -> TypeGuard[TypeCertified]:
|
|
137
|
+
return isinstance(node, antecedent)
|
|
138
|
+
return workhorse
|
|
139
|
+
@staticmethod
|
|
140
|
+
def AnnAssign(node: TypeCertified) -> TypeGuard[ast.AnnAssign]: return be._typeCertified(ast.AnnAssign)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
141
|
+
# 'TypeVar "typeCertified" appears only once in generic function signature. Use "typeCertified" instead Pylance(reportInvalidTypeVarUse)"' HOW THE FUCK IS THAT INVALID WHEN IT IS WORKING PERFECTLY TO PASS THE TYPE INFORMATION--IN YOUR FUCKING STATIC TYPE CHECKER, PYLANCE!!!! Fuck you, and fuck your pretentious language.
|
|
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]
|
|
156
|
+
@staticmethod
|
|
157
|
+
def Compare(node: TypeCertified) -> TypeGuard[ast.Compare]: return be._typeCertified(ast.Compare)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
158
|
+
@staticmethod
|
|
159
|
+
def Constant(node: TypeCertified) -> TypeGuard[ast.Constant]: return be._typeCertified(ast.Constant)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
160
|
+
@staticmethod
|
|
161
|
+
def Expr(node: TypeCertified) -> TypeGuard[ast.Expr]: return be._typeCertified(ast.Expr)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
162
|
+
@staticmethod
|
|
163
|
+
def FunctionDef(node: TypeCertified) -> TypeGuard[ast.FunctionDef]: return be._typeCertified(ast.FunctionDef)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
164
|
+
@staticmethod
|
|
165
|
+
def Import(node: TypeCertified) -> TypeGuard[ast.Import]: return be._typeCertified(ast.Import)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
166
|
+
@staticmethod
|
|
167
|
+
def ImportFrom(node: TypeCertified) -> TypeGuard[ast.ImportFrom]: return be._typeCertified(ast.ImportFrom)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
168
|
+
@staticmethod
|
|
169
|
+
def keyword(node: TypeCertified) -> TypeGuard[ast.keyword]: return be._typeCertified(ast.keyword)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
170
|
+
@staticmethod
|
|
171
|
+
def Module(node: TypeCertified) -> TypeGuard[ast.Module]: return be._typeCertified(ast.Module)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
172
|
+
@staticmethod
|
|
173
|
+
def Name(node: TypeCertified) -> TypeGuard[ast.Name]: return be._typeCertified(ast.Name)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
174
|
+
@staticmethod
|
|
175
|
+
def Return(node: TypeCertified) -> TypeGuard[ast.Return]: return be._typeCertified(ast.Return)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
176
|
+
@staticmethod
|
|
177
|
+
def Starred(node: TypeCertified) -> TypeGuard[ast.Starred]: return be._typeCertified(ast.Starred)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
178
|
+
@staticmethod
|
|
179
|
+
def Subscript(node: TypeCertified) -> TypeGuard[ast.Subscript]: return be._typeCertified(ast.Subscript)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
180
|
+
@staticmethod
|
|
181
|
+
def UnaryOp(node: TypeCertified) -> TypeGuard[ast.UnaryOp]: return be._typeCertified(ast.UnaryOp)(node) # pyright: ignore [reportInvalidTypeVarUse]
|
|
182
|
+
|
|
183
|
+
class ifThis:
|
|
184
|
+
@staticmethod
|
|
185
|
+
def equals(this: Any) -> Callable[[Any], TypeGuard[Any] | bool]:
|
|
186
|
+
return lambda node: node == this
|
|
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)
|
|
206
|
+
@staticmethod
|
|
207
|
+
def is_keyword_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.keyword] | bool]:
|
|
208
|
+
"""see also `isArgument_Identifier`"""
|
|
209
|
+
return lambda node: be.keyword(node) and 又.arg(ifThis._Identifier(identifier))(node)
|
|
210
|
+
@staticmethod
|
|
211
|
+
def is_arg_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.arg] | bool]:
|
|
212
|
+
"""see also `isArgument_Identifier`"""
|
|
213
|
+
return lambda node: be.arg(node) and 又.arg(ifThis._Identifier(identifier))(node)
|
|
214
|
+
@staticmethod
|
|
215
|
+
def isClassDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.ClassDef] | bool]:
|
|
216
|
+
return lambda node: be.ClassDef(node) and 又.name(ifThis._Identifier(identifier))(node)
|
|
217
|
+
@staticmethod
|
|
218
|
+
def isAssignAndValueIsCall_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Assign] | bool]:
|
|
219
|
+
return lambda node: be.Assign(node) and 又.value(ifThis.isCall_Identifier(identifier))(node)
|
|
220
|
+
@staticmethod
|
|
221
|
+
def isAssignAndValueIsCallAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Assign] | bool]:
|
|
222
|
+
return ifThis.isAssignAndValueIs(ifThis.isCallAttributeNamespace_Identifier(namespace, identifier))
|
|
223
|
+
@staticmethod
|
|
224
|
+
def is_keywordAndValueIsConstant(node: TypeCertified) -> TypeGuard[ast.keyword]: # pyright: ignore [reportInvalidTypeVarUse]
|
|
225
|
+
return be.keyword(node) and 又.value(be.Constant)(node)
|
|
226
|
+
@staticmethod
|
|
227
|
+
def is_keyword_IdentifierEqualsConstantValue(identifier: ast_Identifier, ConstantValue: Any) -> Callable[[ast.AST], TypeGuard[ast.keyword] | bool]:
|
|
228
|
+
return lambda node: ifThis.is_keyword_Identifier(identifier)(node) and ifThis.is_keywordAndValueIsConstant(node) and 又.value(ifThis.isConstantEquals(ConstantValue))(node)
|
|
229
|
+
@staticmethod
|
|
230
|
+
def isAnnAssign_targetIs(targetPredicate: Callable[[Ima_targetTypeUNEDITED], TypeGuard[Ima_targetTypeUNEDITED] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
|
|
231
|
+
def workhorse(node: TypeCertified) -> TypeGuard[ast.AnnAssign] | bool: # pyright: ignore [reportInvalidTypeVarUse]
|
|
232
|
+
return be.AnnAssign(node) and 又.target(targetPredicate)(node)
|
|
233
|
+
return workhorse
|
|
234
|
+
@staticmethod
|
|
235
|
+
def isAnnAssignAndAnnotationIsName(node: TypeCertified) -> TypeGuard[ast.AnnAssign] | bool: # pyright: ignore [reportInvalidTypeVarUse]
|
|
236
|
+
return be.AnnAssign(node) and be.Name(DOT.annotation(node))
|
|
237
|
+
# return be.AnnAssign(node) and 又.annotation(be.Name)(node)
|
|
238
|
+
@staticmethod
|
|
239
|
+
def isAugAssign_targetIs(targetPredicate: Callable[[Ima_targetTypeUNEDITED], TypeGuard[Ima_targetTypeUNEDITED] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AugAssign] | bool]:
|
|
240
|
+
def workhorse(node: TypeCertified) -> TypeGuard[ast.AugAssign] | bool: # pyright: ignore [reportInvalidTypeVarUse]
|
|
241
|
+
return be.AugAssign(node) and 又.target(targetPredicate)(node)
|
|
242
|
+
return workhorse
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
def isAnyCompare(node: TypeCertified) -> TypeGuard[ast.BoolOp | ast.Compare]: # pyright: ignore [reportInvalidTypeVarUse]
|
|
246
|
+
return be.Compare(node) or be.BoolOp(node)
|
|
247
|
+
@staticmethod
|
|
248
|
+
def isConstantEquals(value: Any) -> Callable[[ast.AST], TypeGuard[ast.Constant] | bool]:
|
|
249
|
+
return lambda node: be.Constant(node) and 又.value(ifThis.equals(value))(node)
|
|
250
|
+
@staticmethod
|
|
251
|
+
def isReturnAnyCompare(node: TypeCertified) -> TypeGuard[ast.Return] | bool: # pyright: ignore [reportInvalidTypeVarUse] # pyright: ignore [reportInvalidTypeVarUse]
|
|
252
|
+
return be.Return(node) and 又.value(ifThis.isAnyCompare)(node)
|
|
253
|
+
@staticmethod
|
|
254
|
+
def isReturnUnaryOp(node: TypeCertified) -> TypeGuard[ast.Return] | bool: # pyright: ignore [reportInvalidTypeVarUse]
|
|
255
|
+
return be.Return(node) and 又.value(be.UnaryOp)(node)
|
|
256
|
+
|
|
257
|
+
# ================================================================
|
|
258
|
+
# Nested identifier
|
|
259
|
+
@staticmethod
|
|
260
|
+
def _nestedJunction_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute | ast.Starred | ast.Subscript] | bool]:
|
|
261
|
+
def workhorse(node: TypeCertified) -> TypeGuard[ast.Attribute | ast.Starred | ast.Subscript] | bool: # pyright: ignore [reportInvalidTypeVarUse]
|
|
262
|
+
return ifThis.isName_Identifier(identifier)(node) or ifThis.isAttribute_Identifier(identifier)(node) or ifThis.isSubscript_Identifier(identifier)(node) or ifThis.isStarred_Identifier(identifier)(node)
|
|
263
|
+
return workhorse
|
|
264
|
+
@staticmethod
|
|
265
|
+
def isAttribute_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
|
|
266
|
+
"""node is `ast.Attribute` and the top-level `ast.Name` is `identifier`"""
|
|
267
|
+
def workhorse(node: TypeCertified) -> TypeGuard[ast.Attribute]: # pyright: ignore [reportInvalidTypeVarUse]
|
|
268
|
+
return be.Attribute(node) and 又.value(ifThis._nestedJunction_Identifier(identifier))(node)
|
|
269
|
+
return workhorse
|
|
270
|
+
@staticmethod
|
|
271
|
+
def isStarred_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Starred] | bool]:
|
|
272
|
+
"""node is `ast.Starred` and the top-level `ast.Name` is `identifier`"""
|
|
273
|
+
def workhorse(node: TypeCertified) -> TypeGuard[ast.Starred]: # pyright: ignore [reportInvalidTypeVarUse]
|
|
274
|
+
return be.Starred(node) and 又.value(ifThis._nestedJunction_Identifier(identifier))(node)
|
|
275
|
+
return workhorse
|
|
276
|
+
@staticmethod
|
|
277
|
+
def isSubscript_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Subscript] | bool]:
|
|
278
|
+
"""node is `ast.Subscript` and the top-level `ast.Name` is `identifier`"""
|
|
279
|
+
def workhorse(node: TypeCertified) -> TypeGuard[ast.Subscript]: # pyright: ignore [reportInvalidTypeVarUse]
|
|
280
|
+
return be.Subscript(node) and 又.value(ifThis._nestedJunction_Identifier(identifier))(node)
|
|
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]
|
|
287
|
+
return workhorse
|
|
288
|
+
|
|
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
|
+
@staticmethod
|
|
322
|
+
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
|
+
return lambda node: predicate(node) and ifThis.matchesNoDescendant(predicate)(node)
|
|
325
|
+
@staticmethod
|
|
326
|
+
def matchesNoDescendant(predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
|
|
327
|
+
"""Create a predicate that returns True if no descendant of the node matches the given predicate."""
|
|
328
|
+
def workhorse(node: TypeCertified) -> bool: # pyright: ignore [reportInvalidTypeVarUse]
|
|
329
|
+
for descendant in ast.walk(node):
|
|
330
|
+
if descendant is not node and predicate(descendant):
|
|
331
|
+
return False
|
|
332
|
+
return True
|
|
333
|
+
return workhorse
|
|
334
|
+
|
|
335
|
+
@staticmethod
|
|
336
|
+
def CallReallyIs(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
337
|
+
return ifThis.isCall_Identifier(identifier) or ifThis.isCallAttributeNamespace_Identifier(namespace, identifier)
|
|
338
|
+
@staticmethod
|
|
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)
|
|
348
|
+
|
|
349
|
+
@staticmethod
|
|
350
|
+
def isCallToName(node: TypeCertified) -> TypeGuard[ast.Call]: # pyright: ignore [reportInvalidTypeVarUse]
|
|
351
|
+
return be.Call(node) and 又.func(be.Name)(node)
|
|
352
|
+
@staticmethod
|
|
353
|
+
def ast_IdentifierIn(container: Container[ast_Identifier]) -> Callable[[ast_Identifier], TypeGuard[ast_Identifier] | bool]:
|
|
354
|
+
return lambda node: node in container
|
|
355
|
+
# This bullshit is for the crappy function inliner I made.
|
|
356
|
+
@staticmethod
|
|
357
|
+
def CallDoesNotCallItselfAndNameDOTidIsIn(container: Container[ast_Identifier]) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
358
|
+
return lambda node: ifThis.isCallToName(node) and 又.func(又.id(ifThis.ast_IdentifierIn(container)))(node) and ifThis.CallDoesNotCallItself("", node.func.id)(node) # type: ignore
|