astToolkit 0.1.4__tar.gz → 0.2.1__tar.gz

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 (42) hide show
  1. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/PKG-INFO +1 -1
  2. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/__init__.py +1 -0
  3. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolBe.py +33 -27
  4. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolIfThis.py +0 -16
  5. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolkitNodeVisitor.py +8 -8
  6. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_types.py +8 -7
  7. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/transformationTools.py +12 -4
  8. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit.egg-info/PKG-INFO +1 -1
  9. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit.egg-info/SOURCES.txt +6 -3
  10. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/pyproject.toml +1 -1
  11. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/toolFactory/Z0Z_hardcoded.py +16 -7
  12. asttoolkit-0.2.1/toolFactory/Z0Z_makeAstTools.py +42 -0
  13. asttoolkit-0.2.1/toolFactory/__init__.py +27 -0
  14. asttoolkit-0.2.1/toolFactory/_snippets.py +6 -0
  15. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/toolFactory/astFactory.py +45 -44
  16. asttoolkit-0.2.1/toolFactory/databaseASTCreation.py +154 -0
  17. asttoolkit-0.2.1/toolFactory/datacenter.py +131 -0
  18. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/toolFactory/docstrings.py +20 -7
  19. asttoolkit-0.2.1/toolFactory/factory3.py +319 -0
  20. asttoolkit-0.1.4/toolFactory/astFactory_annex.py → asttoolkit-0.2.1/toolFactory/factory_annex.py +2 -1
  21. asttoolkit-0.1.4/toolFactory/Z0Z_makeAstTools.py +0 -36
  22. asttoolkit-0.1.4/toolFactory/__init__.py +0 -16
  23. asttoolkit-0.1.4/toolFactory/startHere.py +0 -11
  24. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/LICENSE +0 -0
  25. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/README.md +0 -0
  26. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_astTypes.py +0 -0
  27. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolClassIsAndAttribute.py +0 -0
  28. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolDOT.py +0 -0
  29. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolGrab.py +0 -0
  30. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolMake.py +0 -0
  31. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolThen.py +0 -0
  32. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolkitAST.py +0 -0
  33. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_toolkitContainers.py +0 -0
  34. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/_typesSpecial.py +0 -0
  35. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/py.typed +0 -0
  36. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit/theSSOT.py +0 -0
  37. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit.egg-info/dependency_links.txt +0 -0
  38. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit.egg-info/requires.txt +0 -0
  39. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/astToolkit.egg-info/top_level.txt +0 -0
  40. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/setup.cfg +0 -0
  41. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/tests/test_basic.py +0 -0
  42. {asttoolkit-0.1.4 → asttoolkit-0.2.1}/toolFactory/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astToolkit
3
- Version: 0.1.4
3
+ Version: 0.2.1
4
4
  Summary: A powerfully composable, type-safe toolkit for Python abstract syntax tree (AST) manipulation, analysis, transformation, and code generation with a layered architecture designed for building sophisticated code processing assembly-lines.
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  License: CC-BY-NC-4.0
@@ -13,6 +13,7 @@ from astToolkit._types import (
13
13
  NodeORattribute as NodeORattribute,
14
14
  str_nameDOTname as str_nameDOTname,
15
15
  个 as 个,
16
+ 个return as 个return,
16
17
  )
17
18
 
18
19
  from astToolkit._toolkitNodeVisitor import (
@@ -1,7 +1,7 @@
1
1
  """This file is generated automatically, so changes to this file will be lost."""
2
- from astToolkit import astDOTTryStar, astDOTParamSpec, astDOTtype_param, astDOTTypeAlias, astDOTTypeVar, astDOTTypeVarTuple
3
2
  from typing import TypeGuard
4
3
  import ast
4
+ import sys
5
5
 
6
6
  class Be:
7
7
  """
@@ -159,14 +159,14 @@ class Be:
159
159
  def Eq(node: ast.AST) -> TypeGuard[ast.Eq]:
160
160
  return isinstance(node, ast.Eq)
161
161
 
162
- @staticmethod
163
- def excepthandler(node: ast.AST) -> TypeGuard[ast.excepthandler]:
164
- return isinstance(node, ast.excepthandler)
165
-
166
162
  @staticmethod
167
163
  def ExceptHandler(node: ast.AST) -> TypeGuard[ast.ExceptHandler]:
168
164
  return isinstance(node, ast.ExceptHandler)
169
165
 
166
+ @staticmethod
167
+ def excepthandler(node: ast.AST) -> TypeGuard[ast.excepthandler]:
168
+ return isinstance(node, ast.excepthandler)
169
+
170
170
  @staticmethod
171
171
  def Expr(node: ast.AST) -> TypeGuard[ast.Expr]:
172
172
  return isinstance(node, ast.Expr)
@@ -335,14 +335,14 @@ class Be:
335
335
  def MatMult(node: ast.AST) -> TypeGuard[ast.MatMult]:
336
336
  return isinstance(node, ast.MatMult)
337
337
 
338
- @staticmethod
339
- def mod(node: ast.AST) -> TypeGuard[ast.mod]:
340
- return isinstance(node, ast.mod)
341
-
342
338
  @staticmethod
343
339
  def Mod(node: ast.AST) -> TypeGuard[ast.Mod]:
344
340
  return isinstance(node, ast.Mod)
345
341
 
342
+ @staticmethod
343
+ def mod(node: ast.AST) -> TypeGuard[ast.mod]:
344
+ return isinstance(node, ast.mod)
345
+
346
346
  @staticmethod
347
347
  def Module(node: ast.AST) -> TypeGuard[ast.Module]:
348
348
  return isinstance(node, ast.Module)
@@ -382,10 +382,11 @@ class Be:
382
382
  @staticmethod
383
383
  def Or(node: ast.AST) -> TypeGuard[ast.Or]:
384
384
  return isinstance(node, ast.Or)
385
+ if sys.version_info >= (3, 12):
385
386
 
386
- @staticmethod
387
- def ParamSpec(node: ast.AST) -> TypeGuard[astDOTParamSpec]:
388
- return isinstance(node, astDOTParamSpec)
387
+ @staticmethod
388
+ def ParamSpec(node: ast.AST) -> TypeGuard[ast.ParamSpec]:
389
+ return isinstance(node, ast.ParamSpec)
389
390
 
390
391
  @staticmethod
391
392
  def Pass(node: ast.AST) -> TypeGuard[ast.Pass]:
@@ -446,10 +447,11 @@ class Be:
446
447
  @staticmethod
447
448
  def Try(node: ast.AST) -> TypeGuard[ast.Try]:
448
449
  return isinstance(node, ast.Try)
450
+ if sys.version_info >= (3, 11):
449
451
 
450
- @staticmethod
451
- def TryStar(node: ast.AST) -> TypeGuard[astDOTTryStar]:
452
- return isinstance(node, astDOTTryStar)
452
+ @staticmethod
453
+ def TryStar(node: ast.AST) -> TypeGuard[ast.TryStar]:
454
+ return isinstance(node, ast.TryStar)
453
455
 
454
456
  @staticmethod
455
457
  def Tuple(node: ast.AST) -> TypeGuard[ast.Tuple]:
@@ -458,26 +460,30 @@ class Be:
458
460
  @staticmethod
459
461
  def type_ignore(node: ast.AST) -> TypeGuard[ast.type_ignore]:
460
462
  return isinstance(node, ast.type_ignore)
463
+ if sys.version_info >= (3, 12):
461
464
 
462
- @staticmethod
463
- def type_param(node: ast.AST) -> TypeGuard[astDOTtype_param]:
464
- return isinstance(node, astDOTtype_param)
465
+ @staticmethod
466
+ def type_param(node: ast.AST) -> TypeGuard[ast.type_param]:
467
+ return isinstance(node, ast.type_param)
468
+ if sys.version_info >= (3, 12):
465
469
 
466
- @staticmethod
467
- def TypeAlias(node: ast.AST) -> TypeGuard[astDOTTypeAlias]:
468
- return isinstance(node, astDOTTypeAlias)
470
+ @staticmethod
471
+ def TypeAlias(node: ast.AST) -> TypeGuard[ast.TypeAlias]:
472
+ return isinstance(node, ast.TypeAlias)
469
473
 
470
474
  @staticmethod
471
475
  def TypeIgnore(node: ast.AST) -> TypeGuard[ast.TypeIgnore]:
472
476
  return isinstance(node, ast.TypeIgnore)
477
+ if sys.version_info >= (3, 12):
473
478
 
474
- @staticmethod
475
- def TypeVar(node: ast.AST) -> TypeGuard[astDOTTypeVar]:
476
- return isinstance(node, astDOTTypeVar)
479
+ @staticmethod
480
+ def TypeVar(node: ast.AST) -> TypeGuard[ast.TypeVar]:
481
+ return isinstance(node, ast.TypeVar)
482
+ if sys.version_info >= (3, 12):
477
483
 
478
- @staticmethod
479
- def TypeVarTuple(node: ast.AST) -> TypeGuard[astDOTTypeVarTuple]:
480
- return isinstance(node, astDOTTypeVarTuple)
484
+ @staticmethod
485
+ def TypeVarTuple(node: ast.AST) -> TypeGuard[ast.TypeVarTuple]:
486
+ return isinstance(node, ast.TypeVarTuple)
481
487
 
482
488
  @staticmethod
483
489
  def UAdd(node: ast.AST) -> TypeGuard[ast.UAdd]:
@@ -44,12 +44,6 @@ class IfThis:
44
44
  """see also `isArgument_Identifier`"""
45
45
  return lambda node: Be.keyword(node) and IfThis.isIdentifier(identifier)(DOT.arg(node))
46
46
 
47
- @staticmethod
48
- def isAnnAssign_targetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
49
- def workhorse(node: ast.AST) -> TypeGuard[ast.AnnAssign] | bool:
50
- return Be.AnnAssign(node) and targetPredicate(DOT.target(node))
51
- return workhorse
52
-
53
47
  @staticmethod
54
48
  def isArgument_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.arg | ast.keyword] | bool]:
55
49
  return lambda node: (Be.arg(node) or Be.keyword(node)) and IfThis.isIdentifier(identifier)(DOT.arg(node))
@@ -58,10 +52,6 @@ class IfThis:
58
52
  def isAssignAndTargets0Is(targets0Predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.AnnAssign] | bool]:
59
53
  """ `node` is `ast.Assign` and `node.targets[0]` matches `targets0Predicate`."""
60
54
  return lambda node: Be.Assign(node) and targets0Predicate(node.targets[0])
61
- @staticmethod
62
- def isAssignAndValueIs(valuePredicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], TypeGuard[ast.Assign] | bool]:
63
- """ `node` is `ast.Assign` and `node.value` matches `valuePredicate`. """
64
- return lambda node: Be.Assign(node) and valuePredicate(DOT.value(node))
65
55
 
66
56
  @staticmethod
67
57
  def isAttribute_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
@@ -82,12 +72,6 @@ class IfThis:
82
72
  def isAttributeNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Attribute] | bool]:
83
73
  return lambda node: IfThis.isAttributeName(node) and IfThis.isName_Identifier(namespace)(DOT.value(node)) and IfThis.isIdentifier(identifier)(DOT.attr(node))
84
74
 
85
- @staticmethod
86
- def isAugAssignAndTargetIs(targetPredicate: Callable[[ast.expr], TypeGuard[ast.expr] | bool]) -> Callable[[ast.AST], TypeGuard[ast.AugAssign] | bool]:
87
- def workhorse(node: ast.AST) -> TypeGuard[ast.AugAssign] | bool:
88
- return Be.AugAssign(node) and targetPredicate(DOT.target(node))
89
- return workhorse
90
-
91
75
  @staticmethod
92
76
  def isCall_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
93
77
  def workhorse(node: ast.AST) -> TypeGuard[ast.Call] | bool:
@@ -15,12 +15,13 @@ structures, creating a complete workflow for code analysis and transformation.
15
15
  """
16
16
 
17
17
  from collections.abc import Callable
18
- from typing import Any
18
+ from typing import Any, cast, Generic, TypeGuard, TypeVar
19
19
  import ast
20
+ from astToolkit import NodeORattribute, 个, 个return
20
21
 
21
22
  # TODO Identify the logic that narrows the type and can help the user during static type checking.
22
23
 
23
- class NodeTourist(ast.NodeVisitor):
24
+ class NodeTourist(ast.NodeVisitor, Generic[个, 个return]):
24
25
  """
25
26
  Visit and extract information from AST nodes that match a predicate.
26
27
 
@@ -31,19 +32,18 @@ class NodeTourist(ast.NodeVisitor):
31
32
  This class is particularly useful for analyzing AST structures, extracting specific nodes or node properties, and
32
33
  gathering information about code patterns.
33
34
  """
34
- def __init__(self, findThis: Callable[..., Any], doThat: Callable[..., Any]) -> None:
35
+ def __init__(self, findThis: Callable[[ast.AST], TypeGuard[个] | bool], doThat: Callable[[个], 个return]) -> None:
35
36
  self.findThis = findThis
36
37
  self.doThat = doThat
37
- self.nodeCaptured: Any | None = None
38
+ self.nodeCaptured: 个return | None = None
38
39
 
39
40
  def visit(self, node: ast.AST) -> None:
40
41
  if self.findThis(node):
41
- nodeActionReturn = self.doThat(node)
42
- if nodeActionReturn is not None:
43
- self.nodeCaptured = nodeActionReturn
42
+ node = cast(个, node)
43
+ self.nodeCaptured = self.doThat(node)
44
44
  self.generic_visit(node)
45
45
 
46
- def captureLastMatch(self, node: ast.AST) -> Any | None:
46
+ def captureLastMatch(self, node: ast.AST) -> 个return | None:
47
47
  self.nodeCaptured = None
48
48
  self.visit(node)
49
49
  return self.nodeCaptured
@@ -4,12 +4,6 @@ import ast
4
4
 
5
5
  # TODO understand typing.
6
6
 
7
- # NOTE Prototype of an idea to subclass composable methods so that typing information
8
- # can extend beyond the top level of the ast node.
9
- # To cover all cases, quantity of necessary classes = sum of (for each class: for each attribute: attribute * number of valid types). If an attribute has type ast.expr, for example, then there are 27 valid types just for that attribute. There would be thousands of subclasses like ImaCallToName.
10
- # class ImaCallToName(ast.Call):
11
- # func: ast.Name # pyright: ignore[reportIncompatibleVariableOverride]
12
-
13
7
  # Type hints through TypeAlias or type "hints" through the identifier name.
14
8
  ast_expr_Slice: typing_TypeAlias = ast.expr
15
9
  ast_Identifier: typing_TypeAlias = str
@@ -17,7 +11,8 @@ str_nameDOTname: typing_TypeAlias = str
17
11
 
18
12
  # Limited success with TypeVar.
19
13
  个 = typing_TypeVar('个', bound = ast.AST, covariant = True)
20
- NodeORattribute = typing_TypeVar('NodeORattribute', bound = ast.AST | ast_expr_Slice | ast_Identifier | str_nameDOTname | bool | Any | None, covariant = True)
14
+ 个return = typing_TypeVar('个return', covariant = True)
15
+ NodeORattribute = typing_TypeVar('NodeORattribute', bound = ast.AST | ast_Identifier | str_nameDOTname | bool | Any | None, covariant = True)
21
16
 
22
17
  # For my reference, all ast classes by subgroup:
23
18
  Ima_ast_boolop: typing_TypeAlias = ast.boolop | ast.And | ast.Or
@@ -34,3 +29,9 @@ Ima_ast_type_param: typing_TypeAlias = astDOTtype_param | astDOTParamSpec | astD
34
29
  Ima_ast_unaryop: typing_TypeAlias = ast.unaryop | ast.Invert | ast.Not | ast.UAdd | ast.USub
35
30
 
36
31
  Ima_ast_orphan = ast.alias | ast.arg | ast.arguments | ast.comprehension | ast.keyword | ast.match_case | ast.withitem
32
+
33
+ # NOTE Prototype of an old idea to subclass composable methods so that typing information
34
+ # can extend beyond the top level of the ast node.
35
+ # To cover all cases, quantity of necessary classes = sum of (for each class: for each attribute: attribute * number of valid types). If an attribute has type ast.expr, for example, then there are 27 valid types just for that attribute. There would be thousands of subclasses like ImaCallToName.
36
+ # class ImaCallToName(ast.Call):
37
+ # func: ast.Name # pyright: ignore[reportIncompatibleVariableOverride]
@@ -1,6 +1,7 @@
1
1
  from astToolkit import (
2
2
  ast_Identifier,
3
3
  Be,
4
+ ClassIsAndAttribute,
4
5
  DOT,
5
6
  FREAKOUT,
6
7
  Grab,
@@ -18,7 +19,7 @@ from collections.abc import Callable, Mapping
18
19
  from copy import deepcopy
19
20
  from os import PathLike
20
21
  from pathlib import PurePath
21
- from typing import Any, cast
22
+ from typing import Any, cast, overload
22
23
  from Z0Z_tools import writeStringToHere
23
24
  import ast
24
25
 
@@ -65,7 +66,8 @@ def inlineFunctionDef(identifierToInline: ast_Identifier, module: ast.Module) ->
65
66
  raise ValueError(f"FunctionDefToInline not found in dictionaryIdentifier2FunctionDef: {identifierToInline = }") from ERRORmessage
66
67
 
67
68
  listIdentifiersCalledFunctions: list[ast_Identifier] = []
68
- findIdentifiersToInline = NodeTourist(findThis = IfThis.isCallToName, doThat = Grab.funcAttribute(cast(Callable[[ast.expr], ast.expr], Grab.idAttribute(cast(Callable[[ast_Identifier], ast_Identifier], Then.appendTo(listIdentifiersCalledFunctions))))))
69
+ findIdentifiersToInline = NodeTourist(findThis = IfThis.isCallToName
70
+ , doThat = Grab.funcAttribute(cast(Callable[[ast.expr], ast.expr], Grab.idAttribute(cast(Callable[[ast_Identifier], ast_Identifier], Then.appendTo(listIdentifiersCalledFunctions))))))
69
71
  findIdentifiersToInline.visit(FunctionDefToInline)
70
72
 
71
73
  dictionary4Inlining: dict[ast_Identifier, ast.FunctionDef] = {}
@@ -94,7 +96,7 @@ def inlineFunctionDef(identifierToInline: ast_Identifier, module: ast.Module) ->
94
96
  for astFunctionDef in dictionary4Inlining.values():
95
97
  inliner.visit(astFunctionDef)
96
98
  else:
97
- inliner = NodeChanger(IfThis.isAssignAndValueIs(IfThis.isCall_Identifier(identifier)),Then.replaceWith(FunctionDefTarget.body[0:-1]))
99
+ inliner = NodeChanger(ClassIsAndAttribute.valueIs(ast.Assign, IfThis.isCall_Identifier(identifier)),Then.replaceWith(FunctionDefTarget.body[0:-1]))
98
100
  for astFunctionDef in dictionary4Inlining.values():
99
101
  inliner.visit(astFunctionDef)
100
102
 
@@ -104,7 +106,7 @@ def inlineFunctionDef(identifierToInline: ast_Identifier, module: ast.Module) ->
104
106
  inliner = NodeChanger(IfThis.isCall_Identifier(identifier), Then.replaceWith(replacement))
105
107
  inliner.visit(FunctionDefToInline)
106
108
  else:
107
- inliner = NodeChanger(IfThis.isAssignAndValueIs(IfThis.isCall_Identifier(identifier)),Then.replaceWith(FunctionDefTarget.body[0:-1]))
109
+ inliner = NodeChanger(ClassIsAndAttribute.valueIs(ast.Assign, IfThis.isCall_Identifier(identifier)),Then.replaceWith(FunctionDefTarget.body[0:-1]))
108
110
  inliner.visit(FunctionDefToInline)
109
111
  ast.fix_missing_locations(FunctionDefToInline)
110
112
  return FunctionDefToInline
@@ -189,6 +191,10 @@ def unparseFindReplace(astTree: 个, mappingFindReplaceNodes: Mapping[ast.AST, a
189
191
  astTree = deepcopy(newTree)
190
192
  return newTree
191
193
 
194
+ # @overload
195
+ # def write_astModule(astModule: ast.AST, pathFilename: PathLike[Any] | PurePath, packageName: ast_Identifier | None = None) -> None:...
196
+ # @overload
197
+ # def write_astModule(ingredients: IngredientsModule, pathFilename: PathLike[Any] | PurePath, packageName: ast_Identifier | None = None) -> None:...
192
198
  def write_astModule(ingredients: IngredientsModule, pathFilename: PathLike[Any] | PurePath, packageName: ast_Identifier | None = None) -> None:
193
199
  """
194
200
  Convert an IngredientsModule to Python source code and write it to a file.
@@ -215,6 +221,8 @@ def write_astModule(ingredients: IngredientsModule, pathFilename: PathLike[Any]
215
221
  Raises:
216
222
  FREAKOUT: If the generated source code is empty.
217
223
  """
224
+ # if ingredients:
225
+ # astModule = Make.Module(ingredients.body, ingredients.type_ignores)
218
226
  astModule = Make.Module(ingredients.body, ingredients.type_ignores)
219
227
  ast.fix_missing_locations(astModule)
220
228
  pythonSource: str = ast.unparse(astModule)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astToolkit
3
- Version: 0.1.4
3
+ Version: 0.2.1
4
4
  Summary: A powerfully composable, type-safe toolkit for Python abstract syntax tree (AST) manipulation, analysis, transformation, and code generation with a layered architecture designed for building sophisticated code processing assembly-lines.
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  License: CC-BY-NC-4.0
@@ -27,8 +27,11 @@ tests/test_basic.py
27
27
  toolFactory/Z0Z_hardcoded.py
28
28
  toolFactory/Z0Z_makeAstTools.py
29
29
  toolFactory/__init__.py
30
+ toolFactory/_snippets.py
30
31
  toolFactory/astFactory.py
31
- toolFactory/astFactory_annex.py
32
+ toolFactory/databaseASTCreation.py
33
+ toolFactory/datacenter.py
32
34
  toolFactory/docstrings.py
33
- toolFactory/py.typed
34
- toolFactory/startHere.py
35
+ toolFactory/factory3.py
36
+ toolFactory/factory_annex.py
37
+ toolFactory/py.typed
@@ -36,7 +36,7 @@ optional-dependencies = { testing = [
36
36
  readme = { file = "README.md", content-type = "text/markdown" }
37
37
  requires-python = ">=3.10"
38
38
  urls = { Donate = "https://www.patreon.com/integrated", Homepage = "https://github.com/hunterhogan/astToolkit", Issues = "https://github.com/hunterhogan/astToolkit/issues", Repository = "https://github.com/hunterhogan/astToolkit.git" }
39
- version = "0.1.4"
39
+ version = "0.2.1"
40
40
 
41
41
  [tool.coverage]
42
42
  report = { exclude_lines = [
@@ -1,17 +1,26 @@
1
1
  from pathlib import Path
2
2
  from typing import TypeAlias as typing_TypeAlias
3
+ import ast
3
4
 
4
5
  ast_Identifier: typing_TypeAlias = str
5
- fileExtension: str = '.py'
6
+ str_nameDOTname: typing_TypeAlias = str
7
+
8
+ pythonVersionMinorMinimum: int = 10
9
+ sys_version_infoMinimum: tuple[int, int] = (3, 10)
10
+ sys_version_infoTarget: tuple[int, int] = (3, 13)
11
+
12
+ class FREAKOUT(Exception): pass
13
+
14
+ # filesystem and namespace ===============================================
6
15
  packageName: ast_Identifier = 'astToolkit'
16
+ moduleIdentifierPrefix: str = '_tool'
17
+ keywordArgumentsIdentifier: ast_Identifier = 'keywordArguments'
18
+
7
19
  pathRoot = Path('/apps') / packageName
8
20
  pathPackage = pathRoot / packageName
21
+ pathToolFactory = pathRoot / 'toolFactory'
9
22
  pathTypeshed = pathRoot / 'typeshed' / 'stdlib'
10
- str_nameDOTname: typing_TypeAlias = str
11
- sys_version_infoMinimum: tuple[int, int] = (3, 10)
12
- sys_version_infoTarget: tuple[int, int] = (3, 13)
13
23
 
14
- listASTSubclasses: list[str] = ['_Slice', 'AST', 'binaryop', 'boolop', 'cmpop', 'excepthandler', 'expr_context', 'expr', 'mod', 'operator', 'pattern', 'stmt', 'type_ignore', 'type_param', 'unaryop',]
24
+ pathFilenameDatabaseAST = pathToolFactory / 'databaseAST.csv'
15
25
 
16
- class FREAKOUT(Exception):
17
- pass
26
+ fileExtension: str = '.py'
@@ -0,0 +1,42 @@
1
+ from collections.abc import Callable, Sequence
2
+ import typeshed_client.finder
3
+ from toolFactory import FREAKOUT, pathTypeshed, makeTools
4
+ from pathlib import Path
5
+ from typing import Any, TypeAlias as typing_TypeAlias, TypeVar as typing_TypeVar
6
+ import ast
7
+
8
+ ast_expr_Slice: typing_TypeAlias = ast.expr
9
+ ast_Identifier: typing_TypeAlias = str
10
+ str_nameDOTname: typing_TypeAlias = str
11
+
12
+ 个 = typing_TypeVar('个', bound = ast.AST, covariant = True)
13
+ NodeORattribute = typing_TypeVar('NodeORattribute', bound = ast.AST | ast_expr_Slice | ast_Identifier | str_nameDOTname | bool | Any | None, covariant = True)
14
+
15
+ # TODO Some `DOT` methods return lists, notably DOT.targets, which is an attribute of ast.Assign.
16
+ # But, none or almost none of the other functions and methods accept a list as input.
17
+ # This is most obviously a problem in `ClassIsAndAttribute.targetsIs` because the user needs to pass
18
+ # a function that can take list[ast.expr] as a parameter.
19
+ # I don't know if the following works, but it is interesting.
20
+ # ClassIsAndAttribute.targetsIs(ast.Assign, lambda list_expr: any([IfThis.isSubscript_Identifier('foldGroups')(node) for node in list_expr]))
21
+
22
+ class cleverName:
23
+ @staticmethod
24
+ def index(at: int) -> Callable[[Sequence[NodeORattribute]], NodeORattribute]:
25
+ def workhorse(zzz: Sequence[NodeORattribute]) -> NodeORattribute:
26
+ node = zzz[at]
27
+ return node
28
+ return workhorse
29
+
30
+ if __name__ == "__main__":
31
+ search_context = typeshed_client.finder.get_search_context(typeshed=pathTypeshed if pathTypeshed.exists() else None)
32
+
33
+ # pathFilenameStubFile: Path | None = typeshed_client.finder.get_stub_file("_ast", search_context=search_context)
34
+ # if pathFilenameStubFile is None: raise FREAKOUT
35
+ # astStubFile: ast.Module = ast.parse(pathFilenameStubFile.read_text())
36
+ # Z0Z_typesSpecial(astStubFile)
37
+
38
+ pathFilenameStubFile: Path | None = typeshed_client.finder.get_stub_file("ast", search_context=search_context)
39
+ if pathFilenameStubFile is None: raise FREAKOUT
40
+ astStubFile: ast.Module = ast.parse(pathFilenameStubFile.read_text())
41
+
42
+ makeTools(astStubFile)
@@ -0,0 +1,27 @@
1
+ from toolFactory.Z0Z_hardcoded import (
2
+ ast_Identifier as ast_Identifier,
3
+ fileExtension as fileExtension,
4
+ FREAKOUT as FREAKOUT,
5
+ keywordArgumentsIdentifier as keywordArgumentsIdentifier,
6
+ moduleIdentifierPrefix as moduleIdentifierPrefix,
7
+ packageName as packageName,
8
+ pathFilenameDatabaseAST as pathFilenameDatabaseAST,
9
+ pathPackage as pathPackage,
10
+ pathTypeshed as pathTypeshed,
11
+ pythonVersionMinorMinimum as pythonVersionMinorMinimum,
12
+ str_nameDOTname as str_nameDOTname,
13
+ sys_version_infoMinimum as sys_version_infoMinimum,
14
+ sys_version_infoTarget as sys_version_infoTarget,
15
+ )
16
+
17
+ from toolFactory._snippets import (
18
+ astName_overload as astName_overload,
19
+ astName_staticmethod as astName_staticmethod,
20
+ astName_typing_TypeAlias as astName_typing_TypeAlias,
21
+ )
22
+
23
+ from toolFactory.datacenter import (
24
+ getElementsBe as getElementsBe,
25
+ )
26
+
27
+ from toolFactory.astFactory import makeTools as makeTools
@@ -0,0 +1,6 @@
1
+ from typing import cast
2
+ import ast
3
+
4
+ astName_overload = ast.Name('overload')
5
+ astName_staticmethod = ast.Name('staticmethod')
6
+ astName_typing_TypeAlias: ast.expr = cast(ast.expr, ast.Name('typing_TypeAlias'))