mapFolding 0.8.5__py3-none-any.whl → 0.9.0__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 (33) hide show
  1. mapFolding/__init__.py +66 -18
  2. mapFolding/basecamp.py +32 -17
  3. mapFolding/beDRY.py +3 -3
  4. mapFolding/oeis.py +121 -25
  5. mapFolding/someAssemblyRequired/__init__.py +48 -27
  6. mapFolding/someAssemblyRequired/_theTypes.py +11 -15
  7. mapFolding/someAssemblyRequired/_tool_Make.py +40 -12
  8. mapFolding/someAssemblyRequired/_tool_Then.py +59 -25
  9. mapFolding/someAssemblyRequired/_toolboxAntecedents.py +151 -276
  10. mapFolding/someAssemblyRequired/_toolboxContainers.py +185 -51
  11. mapFolding/someAssemblyRequired/_toolboxPython.py +165 -44
  12. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +141 -20
  13. mapFolding/someAssemblyRequired/toolboxNumba.py +93 -52
  14. mapFolding/someAssemblyRequired/transformationTools.py +228 -138
  15. mapFolding/syntheticModules/numbaCount_doTheNeedful.py +0 -1
  16. mapFolding/theSSOT.py +147 -55
  17. mapFolding/toolboxFilesystem.py +1 -1
  18. mapfolding-0.9.0.dist-info/METADATA +177 -0
  19. mapfolding-0.9.0.dist-info/RECORD +46 -0
  20. tests/__init__.py +44 -0
  21. tests/conftest.py +75 -7
  22. tests/test_computations.py +90 -9
  23. tests/test_filesystem.py +32 -33
  24. tests/test_other.py +0 -1
  25. tests/test_tasks.py +2 -2
  26. mapFolding/noHomeYet.py +0 -32
  27. mapFolding/someAssemblyRequired/newInliner.py +0 -22
  28. mapfolding-0.8.5.dist-info/METADATA +0 -190
  29. mapfolding-0.8.5.dist-info/RECORD +0 -48
  30. {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/WHEEL +0 -0
  31. {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/entry_points.txt +0 -0
  32. {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/licenses/LICENSE +0 -0
  33. {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,24 @@
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,
21
+ str_nameDOTname,
9
22
  )
10
23
  from typing import Any
11
24
  import ast
@@ -29,71 +42,86 @@ class Make:
29
42
  @staticmethod
30
43
  def alias(name: ast_Identifier, asname: ast_Identifier | None = None) -> ast.alias:
31
44
  return ast.alias(name, asname)
45
+
32
46
  @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.
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.
34
48
  return ast.AnnAssign(target, annotation, value, simple=int(isinstance(target, ast.Name)), **keywordArguments)
49
+
35
50
  @staticmethod
36
51
  def arg(identifier: ast_Identifier, annotation: ast.expr | None = None, **keywordArguments: intORstr_orNone) -> ast.arg:
37
52
  return ast.arg(identifier, annotation, **keywordArguments)
53
+
38
54
  @staticmethod
39
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:
40
56
  return ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults)
57
+
41
58
  @staticmethod
42
59
  def Assign(listTargets: Any, value: ast.expr, **keywordArguments: intORstr_orNone) -> ast.Assign:
43
60
  return ast.Assign(listTargets, value, **keywordArguments)
61
+
44
62
  @staticmethod
45
63
  def Attribute(value: ast.expr, *attribute: ast_Identifier, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Attribute:
46
64
  """ If two `ast_Identifier` are joined by a dot `.`, they are _usually_ an `ast.Attribute`, but see `ast.ImportFrom`.
47
65
  Parameters:
48
- 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`.)
49
67
  attribute: an `ast_Identifier` after a dot `.`; you can pass multiple `attribute` and they will be chained together.
50
68
  """
51
- # TODO confirm the precision of the docstring.
52
- 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:
53
70
  return ast.Attribute(value=chain, attr=identifier, ctx=context, **keywordArguments)
54
71
  buffaloBuffalo = addDOTattribute(value, attribute[0], context, **keywordArguments)
55
72
  for identifier in attribute[1:None]:
56
73
  buffaloBuffalo = addDOTattribute(buffaloBuffalo, identifier, context, **keywordArguments)
57
74
  return buffaloBuffalo
75
+
58
76
  @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:
77
+ def Call(callee: ast.expr, listArguments: Sequence[ast.expr] | None = None, list_astKeywords: Sequence[ast.keyword] | None = None) -> ast.Call:
62
78
  return ast.Call(func=callee, args=list(listArguments) if listArguments else [], keywords=list(list_astKeywords) if list_astKeywords else [])
79
+
63
80
  @staticmethod
64
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:
65
82
  return ast.ClassDef(name, listBases, list_keyword, body, decorator_list, **keywordArguments)
83
+
66
84
  @staticmethod
67
85
  def Constant(value: Any, **keywordArguments: intORstr_orNone) -> ast.Constant:
68
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."""
69
87
  return ast.Constant(value, **keywordArguments)
88
+
70
89
  @staticmethod
71
90
  def Expr(value: ast.expr, **keywordArguments: int) -> ast.Expr:
72
91
  return ast.Expr(value, **keywordArguments)
92
+
73
93
  @staticmethod
74
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:
75
95
  return ast.FunctionDef(name, argumentsSpecification, body, decorator_list, returns, **keywordArguments)
96
+
76
97
  @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)
98
+ def Import(moduleWithLogicalPath: str_nameDOTname, asname: ast_Identifier | None = None, **keywordArguments: int) -> ast.Import:
99
+ return ast.Import(names=[Make.alias(moduleWithLogicalPath, asname)], **keywordArguments)
100
+
79
101
  @staticmethod
80
- def ImportFrom(moduleIdentifier: ast_Identifier, list_astAlias: list[ast.alias], **keywordArguments: int) -> ast.ImportFrom:
81
- return ast.ImportFrom(moduleIdentifier, list_astAlias, **keywordArguments)
102
+ def ImportFrom(moduleWithLogicalPath: str_nameDOTname, list_astAlias: list[ast.alias], **keywordArguments: int) -> ast.ImportFrom:
103
+ return ast.ImportFrom(moduleWithLogicalPath, list_astAlias, **keywordArguments)
104
+
82
105
  @staticmethod
83
106
  def keyword(keywordArgument: ast_Identifier, value: ast.expr, **keywordArguments: int) -> ast.keyword:
84
107
  return ast.keyword(arg=keywordArgument, value=value, **keywordArguments)
108
+
85
109
  @staticmethod
86
110
  def Module(body: list[ast.stmt] = [], type_ignores: list[ast.TypeIgnore] = []) -> ast.Module:
87
111
  return ast.Module(body, type_ignores)
112
+
88
113
  @staticmethod
89
114
  def Name(identifier: ast_Identifier, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Name:
90
115
  return ast.Name(identifier, context, **keywordArguments)
116
+
91
117
  @staticmethod
92
118
  def Return(value: ast.expr | None = None, **keywordArguments: int) -> ast.Return:
93
119
  return ast.Return(value, **keywordArguments)
120
+
94
121
  @staticmethod
95
122
  def Subscript(value: ast.expr, slice: ast_expr_Slice, context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Subscript:
96
123
  return ast.Subscript(value, slice, context, **keywordArguments)
124
+
97
125
  @staticmethod
98
126
  def Tuple(elements: Sequence[ast.expr] = [], context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Tuple:
99
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