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.
Files changed (34) hide show
  1. mapFolding/__init__.py +60 -13
  2. mapFolding/basecamp.py +32 -17
  3. mapFolding/beDRY.py +4 -5
  4. mapFolding/oeis.py +94 -7
  5. mapFolding/someAssemblyRequired/RecipeJob.py +103 -0
  6. mapFolding/someAssemblyRequired/__init__.py +71 -50
  7. mapFolding/someAssemblyRequired/_theTypes.py +11 -15
  8. mapFolding/someAssemblyRequired/_tool_Make.py +36 -9
  9. mapFolding/someAssemblyRequired/_tool_Then.py +59 -25
  10. mapFolding/someAssemblyRequired/_toolboxAntecedents.py +159 -272
  11. mapFolding/someAssemblyRequired/_toolboxContainers.py +155 -70
  12. mapFolding/someAssemblyRequired/_toolboxPython.py +168 -44
  13. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +154 -39
  14. mapFolding/someAssemblyRequired/toolboxNumba.py +72 -230
  15. mapFolding/someAssemblyRequired/transformationTools.py +370 -141
  16. mapFolding/syntheticModules/{numbaCount_doTheNeedful.py → numbaCount.py} +7 -4
  17. mapFolding/theDao.py +19 -16
  18. mapFolding/theSSOT.py +165 -62
  19. mapFolding/toolboxFilesystem.py +1 -1
  20. mapfolding-0.9.1.dist-info/METADATA +177 -0
  21. mapfolding-0.9.1.dist-info/RECORD +47 -0
  22. tests/__init__.py +44 -0
  23. tests/conftest.py +75 -7
  24. tests/test_computations.py +92 -10
  25. tests/test_filesystem.py +32 -33
  26. tests/test_other.py +0 -1
  27. tests/test_tasks.py +1 -1
  28. mapFolding/someAssemblyRequired/newInliner.py +0 -22
  29. mapfolding-0.8.6.dist-info/METADATA +0 -190
  30. mapfolding-0.8.6.dist-info/RECORD +0 -47
  31. {mapfolding-0.8.6.dist-info → mapfolding-0.9.1.dist-info}/WHEEL +0 -0
  32. {mapfolding-0.8.6.dist-info → mapfolding-0.9.1.dist-info}/entry_points.txt +0 -0
  33. {mapfolding-0.8.6.dist-info → mapfolding-0.9.1.dist-info}/licenses/LICENSE +0 -0
  34. {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
- astClassHasDOTvalue: typing_TypeAlias = ast.AnnAssign | ast.Assign | ast.Attribute | ast.AugAssign | ast.Await | ast.Constant | ast.DictComp | ast.Expr | ast.FormattedValue | ast.keyword | ast.MatchValue | ast.NamedExpr | ast.Return | ast.Starred | ast.Subscript | ast.TypeAlias | ast.Yield | ast.YieldFrom
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
- astClassHasDOTvalue = stuPyd
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
- astClassHasDOTtarget: typing_TypeAlias = ast.AnnAssign | ast.AsyncFor | ast.AugAssign | ast.comprehension | ast.For | ast.NamedExpr
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 | ast_Identifier, covariant=True)
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: 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.
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: Any, value: ast.expr, **keywordArguments: intORstr_orNone) -> ast.Assign:
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 (Often `ast.Name`, but also `ast.Attribute`, `ast.Starred`, and `ast.Subscript`.)
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
- # TODO confirm the precision of the docstring.
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
- # TODO are the types for `callee` comprehensive?
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 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
22
+ class grab:
23
+ """
24
+ Modify specific attributes of AST nodes while preserving the node structure.
13
25
 
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
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 DOTarg(action: Callable[[Any], Any]) -> Callable[[ast.arg | ast.keyword], ast.arg | ast.keyword]:
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 DOTfunc(action: Callable[[Any], Any]) -> Callable[[ast.Call], ast.Call]:
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 DOTid(action: Callable[[Any], Any]) -> Callable[[ast.Name], ast.Name]:
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 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]:
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 getIt(node: ast.AST) -> ast.AST | ast_Identifier:
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: ast.AST | ast_Identifier) -> Callable[[ast.AST], ast.AST | ast_Identifier]:
98
+ def replaceWith(astAST: Any) -> Callable[[Any], Any]:
65
99
  return lambda _replaceMe: astAST
66
100
 
67
101
  @staticmethod