astToolkit 0.3.5__tar.gz → 0.3.7__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 (36) hide show
  1. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/PKG-INFO +5 -5
  2. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/__init__.py +3 -2
  3. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_astTypes.py +5 -7
  4. asttoolkit-0.3.7/astToolkit/_dumpHandmade.py +91 -0
  5. asttoolkit-0.3.7/astToolkit/_dumpHandmade.pyi +43 -0
  6. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_joinClassmethod.py +92 -1
  7. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolBe.py +1 -1
  8. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolClassIsAndAttribute.py +37 -36
  9. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolDOT.py +34 -33
  10. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolGrab.py +21 -21
  11. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolMake.py +13 -13
  12. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolkitAST.py +4 -2
  13. asttoolkit-0.3.7/astToolkit/_toolkitContainers.py +633 -0
  14. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_types.py +1 -1
  15. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/transformationTools.py +2 -13
  16. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit.egg-info/PKG-INFO +5 -5
  17. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit.egg-info/SOURCES.txt +2 -0
  18. asttoolkit-0.3.7/pyproject.toml +83 -0
  19. asttoolkit-0.3.7/tests/test_basic.py +193 -0
  20. asttoolkit-0.3.5/astToolkit/_toolkitContainers.py +0 -300
  21. asttoolkit-0.3.5/pyproject.toml +0 -63
  22. asttoolkit-0.3.5/tests/test_basic.py +0 -24
  23. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/LICENSE +0 -0
  24. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/README.md +0 -0
  25. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_dumpFunctionDef.py +0 -0
  26. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_theSSOT.py +0 -0
  27. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolIfThis.py +0 -0
  28. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolThen.py +0 -0
  29. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/_toolkitNodeVisitor.py +0 -0
  30. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit/py.typed +0 -0
  31. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit.egg-info/dependency_links.txt +0 -0
  32. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit.egg-info/requires.txt +1 -1
  33. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/astToolkit.egg-info/top_level.txt +0 -0
  34. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/setup.cfg +0 -0
  35. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/tests/conftest.py +0 -0
  36. {asttoolkit-0.3.5 → asttoolkit-0.3.7}/tests/test_joinClassmethod.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astToolkit
3
- Version: 0.3.5
3
+ Version: 0.3.7
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
@@ -8,7 +8,7 @@ Project-URL: Donate, https://www.patreon.com/integrated
8
8
  Project-URL: Homepage, https://github.com/hunterhogan/astToolkit
9
9
  Project-URL: Issues, https://github.com/hunterhogan/astToolkit/issues
10
10
  Project-URL: Repository, https://github.com/hunterhogan/astToolkit.git
11
- Keywords: ast,abstract syntax tree,code generation,code transformation,ast-analysis,ast-manipulation,ast-traversal,ast-visitor,code-analysis,code-refactoring,static-analysis,python-ast,metaprogramming,visitor-pattern,typed-ast,type-safe,composable-apis,function-inlining,source-code-generation,ast-predicate
11
+ Keywords: abstract syntax tree,ast,ast-analysis,ast-manipulation,ast-predicate,ast-traversal,ast-visitor,code generation,code transformation,code-analysis,code-refactoring,composable-apis,function-inlining,metaprogramming,python-ast,source-code-generation,static-analysis,type-safe,typed-ast,visitor-pattern
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Environment :: Console
14
14
  Classifier: Intended Audience :: Developers
@@ -19,17 +19,17 @@ Classifier: Programming Language :: Python
19
19
  Classifier: Programming Language :: Python :: 3
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
- Classifier: Typing :: Typed
22
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
23
23
  Classifier: Topic :: Software Development :: Code Generators
24
24
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
- Classifier: Topic :: Scientific/Engineering :: Information Analysis
25
+ Classifier: Typing :: Typed
26
26
  Requires-Python: >=3.12
27
27
  Description-Content-Type: text/markdown
28
28
  License-File: LICENSE
29
+ Requires-Dist: Z0Z_tools
29
30
  Requires-Dist: autoflake
30
31
  Requires-Dist: python_minifier
31
32
  Requires-Dist: tomli
32
- Requires-Dist: Z0Z_tools
33
33
  Provides-Extra: testing
34
34
  Requires-Dist: mypy; extra == "testing"
35
35
  Requires-Dist: pytest; extra == "testing"
@@ -25,10 +25,11 @@ maintaining type safety and providing a declarative approach to code transformat
25
25
  from astToolkit._astTypes import * # noqa: F403
26
26
 
27
27
  from astToolkit._types import (
28
- str_nameDOTname as str_nameDOTname,
28
+ identifierDotAttribute as identifierDotAttribute,
29
29
  )
30
30
 
31
- from astToolkit._dumpFunctionDef import dump as dump
31
+ # from astToolkit._dumpFunctionDef import dump as dump
32
+ from astToolkit._dumpHandmade import dump as dump
32
33
 
33
34
  from astToolkit._toolkitNodeVisitor import (
34
35
  NodeChanger as NodeChanger,
@@ -1,14 +1,12 @@
1
1
  """This file is generated automatically, so changes to this file will be lost."""
2
- from types import EllipsisType, NotImplementedType
3
- from typing import Any, TypeAlias as typing_TypeAlias, TypedDict, TypeVar as typing_TypeVar
2
+ from types import EllipsisType
3
+ from typing import Any, TypeAlias as typing_TypeAlias, TypeVar as typing_TypeVar, TypedDict
4
4
  import ast
5
5
  import sys
6
-
7
6
  intORstr: typing_TypeAlias = Any
8
7
  intORstrORtype_params: typing_TypeAlias = Any
9
8
  intORtype_params: typing_TypeAlias = Any
10
- _Scalar: typing_TypeAlias = bool | bytes | complex | EllipsisType | float | int | None | NotImplementedType | range | str
11
- ScalarOrContainerOfScalar: typing_TypeAlias = _Scalar | frozenset['ScalarOrContainerOfScalar'] | tuple['ScalarOrContainerOfScalar', ...]
9
+ ConstantValueType: typing_TypeAlias = bool | bytes | complex | EllipsisType | float | int | None | range | str
12
10
  木 = typing_TypeVar('木', bound=ast.AST, covariant=True)
13
11
  个 = typing_TypeVar('个', covariant=True)
14
12
  个return = typing_TypeVar('个return', covariant=True)
@@ -130,10 +128,10 @@ hasDOTtype_comment: typing_TypeAlias = ast.arg | ast.Assign | ast.AsyncFor | ast
130
128
  hasDOTtype_ignores: typing_TypeAlias = ast.Module
131
129
  hasDOTtype_params: typing_TypeAlias = ast.AsyncFunctionDef | ast.ClassDef | ast.FunctionDef | ast.TypeAlias
132
130
  hasDOTupper: typing_TypeAlias = ast.Slice
133
- hasDOTvalue_ScalarOrContainerOfScalar: typing_TypeAlias = ast.Constant
131
+ hasDOTvalue_ConstantValueType: typing_TypeAlias = ast.Constant
134
132
  hasDOTvalue_boolOrNone: typing_TypeAlias = ast.MatchSingleton
135
133
  hasDOTvalue_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
136
134
  hasDOTvalue_exprOrNone: typing_TypeAlias = ast.AnnAssign | ast.Return | ast.Yield
137
- hasDOTvalue: typing_TypeAlias = hasDOTvalue_ScalarOrContainerOfScalar | hasDOTvalue_boolOrNone | hasDOTvalue_expr | hasDOTvalue_exprOrNone
135
+ hasDOTvalue: typing_TypeAlias = hasDOTvalue_ConstantValueType | hasDOTvalue_boolOrNone | hasDOTvalue_expr | hasDOTvalue_exprOrNone
138
136
  hasDOTvalues: typing_TypeAlias = ast.BoolOp | ast.Dict | ast.JoinedStr
139
137
  hasDOTvararg: typing_TypeAlias = ast.arguments
@@ -0,0 +1,91 @@
1
+ from ast import AST, Constant, MatchSingleton
2
+
3
+ def dump(
4
+ node, annotate_fields=True, include_attributes=False,
5
+ *,
6
+ indent=None, show_empty=False,
7
+ ):
8
+ """
9
+ Return a formatted dump of the tree in node. This is mainly useful for
10
+ debugging purposes. If annotate_fields is true (by default),
11
+ the returned string will show the names and the values for fields.
12
+ If annotate_fields is false, the result string will be more compact by
13
+ omitting unambiguous field names. Attributes such as line
14
+ numbers and column offsets are not dumped by default. If this is wanted,
15
+ include_attributes can be set to true. If indent is a non-negative
16
+ integer or string, then the tree will be pretty-printed with that indent
17
+ level. None (the default) selects the single line representation.
18
+ If show_empty is False, then empty lists and fields that are None
19
+ will be omitted from the output for better readability.
20
+ """
21
+ def _format(node, level=0):
22
+ if indent_str is not None:
23
+ level += 1
24
+ prefix = '\n' + indent_str * level
25
+ sep = ',\n' + indent_str * level
26
+ else:
27
+ prefix = ''
28
+ sep = ', '
29
+ if isinstance(node, AST):
30
+ cls = type(node)
31
+ args = []
32
+ args_buffer = []
33
+ allsimple = True
34
+ keywords = annotate_fields
35
+ for name in node._fields:
36
+ try:
37
+ value = getattr(node, name)
38
+ except AttributeError:
39
+ keywords = True
40
+ continue
41
+ if value is None and getattr(cls, name, ...) is None:
42
+ if show_empty:
43
+ args.append('%s=%s' % (name, value))
44
+ keywords = True
45
+ continue
46
+ elif (
47
+ not show_empty
48
+ and (value is None or value == [])
49
+ # Special cases:
50
+ # `Constant(value=None)` and `MatchSingleton(value=None)`
51
+ and not isinstance(node, (Constant, MatchSingleton))
52
+ ):
53
+ args_buffer.append(repr(value))
54
+ continue
55
+ elif not keywords:
56
+ args.extend(args_buffer)
57
+ args_buffer = []
58
+ value_formatted, simple = _format(value, level)
59
+ allsimple = allsimple and simple
60
+ if keywords:
61
+ args.append('%s=%s' % (name, value_formatted))
62
+ else:
63
+ args.append(value_formatted)
64
+ if include_attributes and node._attributes:
65
+ for name_attributes in node._attributes:
66
+ try:
67
+ value_attributes = getattr(node, name_attributes)
68
+ except AttributeError:
69
+ continue
70
+ if value_attributes is None and getattr(cls, name_attributes, ...) is None:
71
+ continue
72
+ value_attributes_formatted, simple = _format(value_attributes, level)
73
+ allsimple = allsimple and simple
74
+ args.append('%s=%s' % (name_attributes, value_attributes_formatted))
75
+ if allsimple and len(args) <= 3:
76
+ return ('%s(%s)' % (f"{node.__class__.__module__}.{node.__class__.__name__}", ', '.join(args)), not args)
77
+ return ('%s(%s%s)' % (f"{node.__class__.__module__}.{node.__class__.__name__}", prefix, sep.join(args)), False)
78
+ elif isinstance(node, list):
79
+ if not node:
80
+ return ('[]', True)
81
+ return '[%s%s]' % (prefix, sep.join(_format(x, level)[0] for x in node)), False
82
+ return (repr(node), True)
83
+
84
+ if not isinstance(node, AST):
85
+ raise TypeError('expected AST, got %r' % node.__class__.__name__)
86
+ if indent is not None and not isinstance(indent, str):
87
+ indent_str = ' ' * indent
88
+ else:
89
+ indent_str = indent
90
+ return _format(node)[0]
91
+
@@ -0,0 +1,43 @@
1
+ from ast import AST
2
+ from types import EllipsisType, NotImplementedType
3
+ from typing import TypeAlias
4
+
5
+ _Constant: TypeAlias = bool | bytes | complex | EllipsisType | float | int | None | NotImplementedType | range | str
6
+
7
+ ConstantType: TypeAlias = _Constant | frozenset['ConstantType'] | tuple['ConstantType', ...]
8
+
9
+ def dump(
10
+ node: AST,
11
+ annotate_fields: bool = ...,
12
+ include_attributes: bool = ...,
13
+ *,
14
+ indent: int | str | None = ...,
15
+ show_empty: bool = ...,
16
+ ) -> str:
17
+ def _format(node: ConstantType | AST | list[AST] | list[str], level: int = ...) -> tuple[str, bool]:
18
+ # Local variables in _format function
19
+ prefix: str
20
+ sep: str
21
+ cls: type[AST]
22
+ args: list[str]
23
+ args_buffer: list[str]
24
+ allsimple: bool
25
+ keywords: bool
26
+
27
+ name: str
28
+ value: AST | list[AST] | list[str] | ConstantType | bool | bytes | complex | float | int | str
29
+ value_formatted: str
30
+ simple: bool
31
+
32
+ name_attributes: str
33
+ value_attributes: int | None
34
+ value_attributes_formatted: str
35
+
36
+ x: AST | str
37
+
38
+ ...
39
+
40
+ # Local variables in dump function
41
+ indent_str: str | None
42
+
43
+ ...
@@ -1,9 +1,20 @@
1
1
  """This file is generated automatically, so changes to this file will be lost."""
2
2
  from astToolkit import ast_attributes, Make
3
- from collections.abc import Iterable
3
+ from collections.abc import Iterable, Sequence
4
4
  from typing import Unpack
5
5
  import ast
6
6
 
7
+ def boolopJoinMethod(ast_operator: type[ast.boolop], expressions: Sequence[ast.expr], **keywordArguments: Unpack[ast_attributes]) -> ast.expr | ast.BoolOp:
8
+ listExpressions: list[ast.expr] = list(expressions)
9
+ match len(listExpressions):
10
+ case 0:
11
+ expressionsJoined = Make.Constant('', **keywordArguments)
12
+ case 1:
13
+ expressionsJoined = listExpressions[0]
14
+ case _:
15
+ expressionsJoined = Make.BoolOp(ast_operator(), listExpressions, **keywordArguments)
16
+ return expressionsJoined
17
+
7
18
  def operatorJoinMethod(ast_operator: type[ast.operator], expressions: Iterable[ast.expr], **keywordArguments: Unpack[ast_attributes]) -> ast.expr:
8
19
  listExpressions: list[ast.expr] = list(expressions)
9
20
  if not listExpressions:
@@ -13,6 +24,86 @@ def operatorJoinMethod(ast_operator: type[ast.operator], expressions: Iterable[a
13
24
  expressionsJoined = ast.BinOp(left=expressionsJoined, op=ast_operator(), right=expression, **keywordArguments)
14
25
  return expressionsJoined
15
26
 
27
+ class And(ast.And):
28
+ """Identical to the `ast` class but with a method, `join()`, that "joins" expressions using the `ast.BoolOp` class."""
29
+
30
+ @classmethod
31
+ def join(cls, expressions: Sequence[ast.expr], **keywordArguments: Unpack[ast_attributes]) -> ast.expr:
32
+ """
33
+ Create a single `ast.expr` from a sequence of `ast.expr` by forming an `ast.BoolOp`
34
+ that logically "joins" expressions using the `ast.BoolOp` subclass. Like str.join() but for AST expressions.
35
+
36
+ Parameters
37
+ ----------
38
+ expressions : Sequence[ast.expr]
39
+ Collection of expressions to join.
40
+ **keywordArguments : ast._attributes
41
+
42
+ Returns
43
+ -------
44
+ joinedExpression : ast.expr
45
+ Single expression representing the joined expressions.
46
+
47
+ Examples
48
+ --------
49
+ Instead of manually constructing ast.BoolOp structures:
50
+ ```
51
+ ast.BoolOp(
52
+ op=ast.And(),
53
+ values=[ast.Name('Lions'), ast.Name('tigers'), ast.Name('bears')]
54
+ )
55
+ ```
56
+
57
+ Simply use:
58
+ ```
59
+ astToolkit.And.join([ast.Name('Lions'), ast.Name('tigers'), ast.Name('bears')])
60
+ ```
61
+
62
+ Both produce the same AST structure but the join() method eliminates the manual construction.
63
+ Handles single expressions and empty sequences gracefully.
64
+ """
65
+ return boolopJoinMethod(cls, expressions, **keywordArguments)
66
+
67
+ class Or(ast.Or):
68
+ """Identical to the `ast` class but with a method, `join()`, that "joins" expressions using the `ast.BoolOp` class."""
69
+
70
+ @classmethod
71
+ def join(cls, expressions: Sequence[ast.expr], **keywordArguments: Unpack[ast_attributes]) -> ast.expr:
72
+ """
73
+ Create a single `ast.expr` from a sequence of `ast.expr` by forming an `ast.BoolOp`
74
+ that logically "joins" expressions using the `ast.BoolOp` subclass. Like str.join() but for AST expressions.
75
+
76
+ Parameters
77
+ ----------
78
+ expressions : Sequence[ast.expr]
79
+ Collection of expressions to join.
80
+ **keywordArguments : ast._attributes
81
+
82
+ Returns
83
+ -------
84
+ joinedExpression : ast.expr
85
+ Single expression representing the joined expressions.
86
+
87
+ Examples
88
+ --------
89
+ Instead of manually constructing ast.BoolOp structures:
90
+ ```
91
+ ast.BoolOp(
92
+ op=ast.And(),
93
+ values=[ast.Name('Lions'), ast.Name('tigers'), ast.Name('bears')]
94
+ )
95
+ ```
96
+
97
+ Simply use:
98
+ ```
99
+ astToolkit.And.join([ast.Name('Lions'), ast.Name('tigers'), ast.Name('bears')])
100
+ ```
101
+
102
+ Both produce the same AST structure but the join() method eliminates the manual construction.
103
+ Handles single expressions and empty sequences gracefully.
104
+ """
105
+ return boolopJoinMethod(cls, expressions, **keywordArguments)
106
+
16
107
  class Add(ast.Add):
17
108
  """Identical to the `ast` class but with a method, `join()`, that "joins" expressions using the `ast.BinOp` class."""
18
109
 
@@ -52,7 +52,7 @@ class Be:
52
52
 
53
53
  @staticmethod
54
54
  def AST(node: ast.AST) -> TypeGuard[ast.AST]:
55
- return isinstance(node, ast.AST) # pyright: ignore[reportUnnecessaryIsInstance]
55
+ return isinstance(node, ast.AST)
56
56
 
57
57
  @staticmethod
58
58
  def AsyncFor(node: ast.AST) -> TypeGuard[ast.AsyncFor]:
@@ -2,9 +2,10 @@
2
2
  # ruff: noqa: F403, F405
3
3
  """This file is generated automatically, so changes to this file will be lost."""
4
4
  from astToolkit._astTypes import *
5
- from collections.abc import Callable
5
+ from collections.abc import Callable, Sequence
6
6
  from typing import overload, TypeGuard
7
7
  import ast
8
+ import sys
8
9
 
9
10
  class ClassIsAndAttribute:
10
11
  """
@@ -67,18 +68,18 @@ class ClassIsAndAttribute:
67
68
 
68
69
  @staticmethod
69
70
  @overload
70
- def argsIs(astClass: type[hasDOTargs_list_expr], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTargs_list_expr] | bool]:
71
+ def argsIs(astClass: type[hasDOTargs_list_expr], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTargs_list_expr] | bool]:
71
72
  ...
72
73
 
73
74
  @staticmethod
74
- def argsIs(astClass: type[hasDOTargs], attributeCondition: Callable[[ast.arguments], bool] | Callable[[list[ast.arg]], bool] | Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTargs] | bool]:
75
+ def argsIs(astClass: type[hasDOTargs], attributeCondition: Callable[[ast.arguments], bool] | Callable[[Sequence[ast.expr]], bool] | Callable[[list[ast.arg]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTargs] | bool]:
75
76
 
76
77
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTargs] | bool:
77
78
  return isinstance(node, astClass) and attributeCondition(node.args)
78
79
  return workhorse
79
80
 
80
81
  @staticmethod
81
- def argtypesIs(astClass: type[hasDOTargtypes], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTargtypes] | bool]:
82
+ def argtypesIs(astClass: type[hasDOTargtypes], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTargtypes] | bool]:
82
83
 
83
84
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTargtypes] | bool:
84
85
  return isinstance(node, astClass) and attributeCondition(node.argtypes)
@@ -99,7 +100,7 @@ class ClassIsAndAttribute:
99
100
  return workhorse
100
101
 
101
102
  @staticmethod
102
- def basesIs(astClass: type[hasDOTbases], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTbases] | bool]:
103
+ def basesIs(astClass: type[hasDOTbases], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTbases] | bool]:
103
104
 
104
105
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTbases] | bool:
105
106
  return isinstance(node, astClass) and attributeCondition(node.bases)
@@ -112,11 +113,11 @@ class ClassIsAndAttribute:
112
113
 
113
114
  @staticmethod
114
115
  @overload
115
- def bodyIs(astClass: type[hasDOTbody_list_stmt], attributeCondition: Callable[[list[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTbody_list_stmt] | bool]:
116
+ def bodyIs(astClass: type[hasDOTbody_list_stmt], attributeCondition: Callable[[Sequence[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTbody_list_stmt] | bool]:
116
117
  ...
117
118
 
118
119
  @staticmethod
119
- def bodyIs(astClass: type[hasDOTbody], attributeCondition: Callable[[ast.expr], bool] | Callable[[list[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTbody] | bool]:
120
+ def bodyIs(astClass: type[hasDOTbody], attributeCondition: Callable[[ast.expr], bool] | Callable[[Sequence[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTbody] | bool]:
120
121
 
121
122
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTbody] | bool:
122
123
  return isinstance(node, astClass) and attributeCondition(node.body)
@@ -130,7 +131,7 @@ class ClassIsAndAttribute:
130
131
  return workhorse
131
132
 
132
133
  @staticmethod
133
- def casesIs(astClass: type[hasDOTcases], attributeCondition: Callable[[list[ast.match_case]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTcases] | bool]:
134
+ def casesIs(astClass: type[hasDOTcases], attributeCondition: Callable[[Sequence[ast.match_case]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTcases] | bool]:
134
135
 
135
136
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTcases] | bool:
136
137
  return isinstance(node, astClass) and attributeCondition(node.cases)
@@ -151,7 +152,7 @@ class ClassIsAndAttribute:
151
152
  return workhorse
152
153
 
153
154
  @staticmethod
154
- def comparatorsIs(astClass: type[hasDOTcomparators], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTcomparators] | bool]:
155
+ def comparatorsIs(astClass: type[hasDOTcomparators], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTcomparators] | bool]:
155
156
 
156
157
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTcomparators] | bool:
157
158
  return isinstance(node, astClass) and attributeCondition(node.comparators)
@@ -179,7 +180,7 @@ class ClassIsAndAttribute:
179
180
  return workhorse
180
181
 
181
182
  @staticmethod
182
- def decorator_listIs(astClass: type[hasDOTdecorator_list], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTdecorator_list] | bool]:
183
+ def decorator_listIs(astClass: type[hasDOTdecorator_list], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTdecorator_list] | bool]:
183
184
 
184
185
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTdecorator_list] | bool:
185
186
  return isinstance(node, astClass) and attributeCondition(node.decorator_list)
@@ -194,7 +195,7 @@ class ClassIsAndAttribute:
194
195
  return workhorse
195
196
 
196
197
  @staticmethod
197
- def defaultsIs(astClass: type[hasDOTdefaults], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTdefaults] | bool]:
198
+ def defaultsIs(astClass: type[hasDOTdefaults], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTdefaults] | bool]:
198
199
 
199
200
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTdefaults] | bool:
200
201
  return isinstance(node, astClass) and attributeCondition(node.defaults)
@@ -208,7 +209,7 @@ class ClassIsAndAttribute:
208
209
  return workhorse
209
210
 
210
211
  @staticmethod
211
- def eltsIs(astClass: type[hasDOTelts], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTelts] | bool]:
212
+ def eltsIs(astClass: type[hasDOTelts], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTelts] | bool]:
212
213
 
213
214
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTelts] | bool:
214
215
  return isinstance(node, astClass) and attributeCondition(node.elts)
@@ -222,7 +223,7 @@ class ClassIsAndAttribute:
222
223
  return workhorse
223
224
 
224
225
  @staticmethod
225
- def finalbodyIs(astClass: type[hasDOTfinalbody], attributeCondition: Callable[[list[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTfinalbody] | bool]:
226
+ def finalbodyIs(astClass: type[hasDOTfinalbody], attributeCondition: Callable[[Sequence[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTfinalbody] | bool]:
226
227
 
227
228
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTfinalbody] | bool:
228
229
  return isinstance(node, astClass) and attributeCondition(node.finalbody)
@@ -243,7 +244,7 @@ class ClassIsAndAttribute:
243
244
  return workhorse
244
245
 
245
246
  @staticmethod
246
- def generatorsIs(astClass: type[hasDOTgenerators], attributeCondition: Callable[[list[ast.comprehension]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTgenerators] | bool]:
247
+ def generatorsIs(astClass: type[hasDOTgenerators], attributeCondition: Callable[[Sequence[ast.comprehension]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTgenerators] | bool]:
247
248
 
248
249
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTgenerators] | bool:
249
250
  return isinstance(node, astClass) and attributeCondition(node.generators)
@@ -271,7 +272,7 @@ class ClassIsAndAttribute:
271
272
  return workhorse
272
273
 
273
274
  @staticmethod
274
- def ifsIs(astClass: type[hasDOTifs], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTifs] | bool]:
275
+ def ifsIs(astClass: type[hasDOTifs], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTifs] | bool]:
275
276
 
276
277
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTifs] | bool:
277
278
  return isinstance(node, astClass) and attributeCondition(node.ifs)
@@ -285,7 +286,7 @@ class ClassIsAndAttribute:
285
286
  return workhorse
286
287
 
287
288
  @staticmethod
288
- def itemsIs(astClass: type[hasDOTitems], attributeCondition: Callable[[list[ast.withitem]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTitems] | bool]:
289
+ def itemsIs(astClass: type[hasDOTitems], attributeCondition: Callable[[Sequence[ast.withitem]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTitems] | bool]:
289
290
 
290
291
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTitems] | bool:
291
292
  return isinstance(node, astClass) and attributeCondition(node.items)
@@ -307,23 +308,23 @@ class ClassIsAndAttribute:
307
308
 
308
309
  @staticmethod
309
310
  @overload
310
- def keysIs(astClass: type[hasDOTkeys_list_expr], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeys_list_expr] | bool]:
311
+ def keysIs(astClass: type[hasDOTkeys_list_expr], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeys_list_expr] | bool]:
311
312
  ...
312
313
 
313
314
  @staticmethod
314
315
  @overload
315
- def keysIs(astClass: type[hasDOTkeys_list_exprOrNone], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeys_list_exprOrNone] | bool]:
316
+ def keysIs(astClass: type[hasDOTkeys_list_exprOrNone], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeys_list_exprOrNone] | bool]:
316
317
  ...
317
318
 
318
319
  @staticmethod
319
- def keysIs(astClass: type[hasDOTkeys], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeys] | bool]:
320
+ def keysIs(astClass: type[hasDOTkeys], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeys] | bool]:
320
321
 
321
322
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTkeys] | bool:
322
323
  return isinstance(node, astClass) and node.keys != [None] and attributeCondition(node.keys)
323
324
  return workhorse
324
325
 
325
326
  @staticmethod
326
- def keywordsIs(astClass: type[hasDOTkeywords], attributeCondition: Callable[[list[ast.keyword]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeywords] | bool]:
327
+ def keywordsIs(astClass: type[hasDOTkeywords], attributeCondition: Callable[[Sequence[ast.keyword]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkeywords] | bool]:
327
328
 
328
329
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTkeywords] | bool:
329
330
  return isinstance(node, astClass) and attributeCondition(node.keywords)
@@ -337,7 +338,7 @@ class ClassIsAndAttribute:
337
338
  return workhorse
338
339
 
339
340
  @staticmethod
340
- def kw_defaultsIs(astClass: type[hasDOTkw_defaults], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkw_defaults] | bool]:
341
+ def kw_defaultsIs(astClass: type[hasDOTkw_defaults], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkw_defaults] | bool]:
341
342
 
342
343
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTkw_defaults] | bool:
343
344
  return isinstance(node, astClass) and node.kw_defaults != [None] and attributeCondition(node.kw_defaults)
@@ -358,7 +359,7 @@ class ClassIsAndAttribute:
358
359
  return workhorse
359
360
 
360
361
  @staticmethod
361
- def kwd_patternsIs(astClass: type[hasDOTkwd_patterns], attributeCondition: Callable[[list[ast.pattern]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkwd_patterns] | bool]:
362
+ def kwd_patternsIs(astClass: type[hasDOTkwd_patterns], attributeCondition: Callable[[Sequence[ast.pattern]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTkwd_patterns] | bool]:
362
363
 
363
364
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTkwd_patterns] | bool:
364
365
  return isinstance(node, astClass) and attributeCondition(node.kwd_patterns)
@@ -482,7 +483,7 @@ class ClassIsAndAttribute:
482
483
  return workhorse
483
484
 
484
485
  @staticmethod
485
- def opsIs(astClass: type[hasDOTops], attributeCondition: Callable[[list[ast.cmpop]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTops] | bool]:
486
+ def opsIs(astClass: type[hasDOTops], attributeCondition: Callable[[Sequence[ast.cmpop]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTops] | bool]:
486
487
 
487
488
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTops] | bool:
488
489
  return isinstance(node, astClass) and attributeCondition(node.ops)
@@ -502,11 +503,11 @@ class ClassIsAndAttribute:
502
503
 
503
504
  @staticmethod
504
505
  @overload
505
- def orelseIs(astClass: type[hasDOTorelse_list_stmt], attributeCondition: Callable[[list[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTorelse_list_stmt] | bool]:
506
+ def orelseIs(astClass: type[hasDOTorelse_list_stmt], attributeCondition: Callable[[Sequence[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTorelse_list_stmt] | bool]:
506
507
  ...
507
508
 
508
509
  @staticmethod
509
- def orelseIs(astClass: type[hasDOTorelse], attributeCondition: Callable[[ast.expr], bool] | Callable[[list[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTorelse] | bool]:
510
+ def orelseIs(astClass: type[hasDOTorelse], attributeCondition: Callable[[ast.expr], bool] | Callable[[Sequence[ast.stmt]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTorelse] | bool]:
510
511
 
511
512
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTorelse] | bool:
512
513
  return isinstance(node, astClass) and attributeCondition(node.orelse)
@@ -530,7 +531,7 @@ class ClassIsAndAttribute:
530
531
  return workhorse
531
532
 
532
533
  @staticmethod
533
- def patternsIs(astClass: type[hasDOTpatterns], attributeCondition: Callable[[list[ast.pattern]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTpatterns] | bool]:
534
+ def patternsIs(astClass: type[hasDOTpatterns], attributeCondition: Callable[[Sequence[ast.pattern]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTpatterns] | bool]:
534
535
 
535
536
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTpatterns] | bool:
536
537
  return isinstance(node, astClass) and attributeCondition(node.patterns)
@@ -611,28 +612,28 @@ class ClassIsAndAttribute:
611
612
 
612
613
  @staticmethod
613
614
  @overload
614
- def targetIs(astClass: type[hasDOTtarget_expr], attributeCondition: Callable[[ast.expr], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget_expr] | bool]:
615
+ def targetIs(astClass: type[hasDOTtarget_Name], attributeCondition: Callable[[ast.Name], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget_Name] | bool]:
615
616
  ...
616
617
 
617
618
  @staticmethod
618
619
  @overload
619
- def targetIs(astClass: type[hasDOTtarget_Name], attributeCondition: Callable[[ast.Name], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget_Name] | bool]:
620
+ def targetIs(astClass: type[hasDOTtarget_NameOrAttributeOrSubscript], attributeCondition: Callable[[ast.Name | ast.Attribute | ast.Subscript], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget_NameOrAttributeOrSubscript] | bool]:
620
621
  ...
621
622
 
622
623
  @staticmethod
623
624
  @overload
624
- def targetIs(astClass: type[hasDOTtarget_NameOrAttributeOrSubscript], attributeCondition: Callable[[ast.Name | ast.Attribute | ast.Subscript], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget_NameOrAttributeOrSubscript] | bool]:
625
+ def targetIs(astClass: type[hasDOTtarget_expr], attributeCondition: Callable[[ast.expr], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget_expr] | bool]:
625
626
  ...
626
627
 
627
628
  @staticmethod
628
- def targetIs(astClass: type[hasDOTtarget], attributeCondition: Callable[[ast.expr], bool] | Callable[[ast.Name], bool] | Callable[[ast.Name | ast.Attribute | ast.Subscript], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget] | bool]:
629
+ def targetIs(astClass: type[hasDOTtarget], attributeCondition: Callable[[ast.Name], bool] | Callable[[ast.expr], bool] | Callable[[ast.Name | ast.Attribute | ast.Subscript], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtarget] | bool]:
629
630
 
630
631
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTtarget] | bool:
631
632
  return isinstance(node, astClass) and attributeCondition(node.target)
632
633
  return workhorse
633
634
 
634
635
  @staticmethod
635
- def targetsIs(astClass: type[hasDOTtargets], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtargets] | bool]:
636
+ def targetsIs(astClass: type[hasDOTtargets], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtargets] | bool]:
636
637
 
637
638
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTtargets] | bool:
638
639
  return isinstance(node, astClass) and attributeCondition(node.targets)
@@ -667,7 +668,7 @@ class ClassIsAndAttribute:
667
668
  return workhorse
668
669
 
669
670
  @staticmethod
670
- def type_paramsIs(astClass: type[hasDOTtype_params], attributeCondition: Callable[[list[ast.type_param]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtype_params] | bool]:
671
+ def type_paramsIs(astClass: type[hasDOTtype_params], attributeCondition: Callable[[Sequence[ast.type_param]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTtype_params] | bool]:
671
672
 
672
673
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTtype_params] | bool:
673
674
  return isinstance(node, astClass) and attributeCondition(node.type_params)
@@ -682,7 +683,7 @@ class ClassIsAndAttribute:
682
683
 
683
684
  @staticmethod
684
685
  @overload
685
- def valueIs(astClass: type[hasDOTvalue_ScalarOrContainerOfScalar], attributeCondition: Callable[[ScalarOrContainerOfScalar], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTvalue_ScalarOrContainerOfScalar] | bool]:
686
+ def valueIs(astClass: type[hasDOTvalue_ConstantValueType], attributeCondition: Callable[[ConstantValueType], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTvalue_ConstantValueType] | bool]:
686
687
  ...
687
688
 
688
689
  @staticmethod
@@ -701,14 +702,14 @@ class ClassIsAndAttribute:
701
702
  ...
702
703
 
703
704
  @staticmethod
704
- def valueIs(astClass: type[hasDOTvalue], attributeCondition: Callable[[ScalarOrContainerOfScalar], bool] | Callable[[bool], bool] | Callable[[ast.expr], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTvalue] | bool]:
705
+ def valueIs(astClass: type[hasDOTvalue], attributeCondition: Callable[[ast.expr], bool] | Callable[[ConstantValueType], bool] | Callable[[bool], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTvalue] | bool]:
705
706
 
706
707
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTvalue] | bool:
707
708
  return isinstance(node, astClass) and node.value is not None and attributeCondition(node.value)
708
709
  return workhorse
709
710
 
710
711
  @staticmethod
711
- def valuesIs(astClass: type[hasDOTvalues], attributeCondition: Callable[[list[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTvalues] | bool]:
712
+ def valuesIs(astClass: type[hasDOTvalues], attributeCondition: Callable[[Sequence[ast.expr]], bool]) -> Callable[[ast.AST], TypeGuard[hasDOTvalues] | bool]:
712
713
 
713
714
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTvalues] | bool:
714
715
  return isinstance(node, astClass) and attributeCondition(node.values)
@@ -719,4 +720,4 @@ class ClassIsAndAttribute:
719
720
 
720
721
  def workhorse(node: ast.AST) -> TypeGuard[hasDOTvararg] | bool:
721
722
  return isinstance(node, astClass) and node.vararg is not None and attributeCondition(node.vararg)
722
- return workhorse
723
+ return workhorse