micropython-stubber 1.24.0__py3-none-any.whl → 1.24.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: micropython-stubber
3
- Version: 1.24.0
3
+ Version: 1.24.1
4
4
  Summary: Tooling to create and maintain stubs for MicroPython
5
5
  License: MIT
6
6
  Keywords: MicroPython,stubs,vscode,pyright,linting,static type check
@@ -21,7 +21,7 @@ mpflash/mpflash/download.py,sha256=wE4uBSFFMAKOBH4jwHweL0wVYh4vi74t1673ku_IeoA,1
21
21
  mpflash/mpflash/downloaded.py,sha256=nxTWU4lvhcthqvVmzpYHnXCnjD8wJv0KFq2KtaoTO1A,5160
22
22
  mpflash/mpflash/errors.py,sha256=IAidY3qkZsXy6Pm1rdmVFmGyg81ywHhse3itaPctA2w,247
23
23
  mpflash/mpflash/flash/__init__.py,sha256=g4Fp8MiquaDZXIvRJwYRkkll1MMyRud7x6qmwCk9Lgo,2096
24
- mpflash/mpflash/flash/esp.py,sha256=_VfbyYIEaUgAjsD66tjbdgYL6ElkSAfpIMKz6q4QKig,2287
24
+ mpflash/mpflash/flash/esp.py,sha256=CRF8sfIyuDZoYC1luBy92zLm6Qz3dnBBWjuJ3A4_crE,2284
25
25
  mpflash/mpflash/flash/stm32.py,sha256=dqp9BZ4Vr-6GlQcF12TSmRf-5TXkov9qvCpMgeUJc7Y,574
26
26
  mpflash/mpflash/flash/stm32_dfu.py,sha256=W-3JsRQyf3DduoIRXDmGZ35RogqtjQgcJnk-GOtQoLE,3090
27
27
  mpflash/mpflash/flash/uf2/__init__.py,sha256=ucTg1pg7TruwPjecCPWYRpCwWPz-rngv7UYaQ_bMzww,2854
@@ -82,11 +82,11 @@ stubber/codemod/add_comment.py,sha256=CZMjtKO9aarZo1E60QXo80CLJAH05z_ylK6Vvjvb0l
82
82
  stubber/codemod/add_method.py,sha256=fZH-RGi_pzFpi3tF_0AMDbA9A94dlgXMrc3ItpY3Ylw,2609
83
83
  stubber/codemod/board.py,sha256=HDNS8saQIdoPH74MNG9mte0MRBqCOcy3d6f_I0H9J2I,11881
84
84
  stubber/codemod/enrich.py,sha256=mrnhPLgjYQZvxaeMPAcZ_459-XC5rw_SAKsFxLtlMYo,12788
85
- stubber/codemod/merge_docstub.py,sha256=HapJGu4UMYe8SiO5qHxgfOsXYw7caATRgvsJwgX9Fag,22057
85
+ stubber/codemod/merge_docstub.py,sha256=fgi0PVRhN9gGzcOfCUW0ni-C54oGYUKwc5Yk2FsCS3U,22081
86
86
  stubber/codemod/modify_list.py,sha256=xrpFBKug273D9E02owUheZD418BvsIHIZCFj4YDjTxU,2118
87
87
  stubber/codemod/test_enrich.py,sha256=ckJtwo4PsXckcnZGk_2gxRRLQkfKI650pVmdByw_pVo,2820
88
88
  stubber/codemod/utils.py,sha256=3hk7pwyS4KZxewrWLwbOrdA5ympbum-kfL0ZN-M7rlo,2459
89
- stubber/codemod/visitors/typevars.py,sha256=ZLLp6Fyw8jx56Uhhx1sunpUPasN8tJoaCFCugvU7z6c,7448
89
+ stubber/codemod/visitors/type_helpers.py,sha256=FBV6wwPtBiWwZTqEpdhVw-Jghi-gxyMVZE4SyGn7uRU,6812
90
90
  stubber/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
91
  stubber/commands/build_cmd.py,sha256=Zseci4EHxJuiiy7YS-ucmMokDrVLe4j6fPs-PSbwq1k,2813
92
92
  stubber/commands/cli.py,sha256=HY4CqB0PPTmzew2sABNsHeNKDPblcGzzbmvtF46oVsU,1556
@@ -154,8 +154,8 @@ stubber/utils/repos.py,sha256=piUZwtHBXXJ-XPhvw_qXYqO-fy1ktZsb9-7CAwNo2YQ,5896
154
154
  stubber/utils/stubmaker.py,sha256=pO8Bo9JuHo6eeJGJz4hO2PzVJojNYFdJPdVtlgjKkBI,5236
155
155
  stubber/utils/typed_config_toml.py,sha256=ZR7eo-whyL4nhFXj6xs7E121sLuE-ivlUDevII4K2xg,2653
156
156
  stubber/variants.py,sha256=NnwUP-aiGUPAn15BeRRFcBWQUOzAFFnN2oL4u9zio-s,3792
157
- micropython_stubber-1.24.0.dist-info/entry_points.txt,sha256=JoR8NWh8t6pbDyn0WOMCIfRfDQAOGxqbOgJWuxv3Cxw,116
158
- micropython_stubber-1.24.0.dist-info/LICENSE,sha256=Fx9qrL45ayRXgH6QzttboqZEjKXms0w1t_b_nkOqYCU,1572
159
- micropython_stubber-1.24.0.dist-info/METADATA,sha256=VFYvKOoekntu4U0wBy_DcDgbYWsqHKHzUrYJD_zAVDc,25020
160
- micropython_stubber-1.24.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
161
- micropython_stubber-1.24.0.dist-info/RECORD,,
157
+ micropython_stubber-1.24.1.dist-info/entry_points.txt,sha256=JoR8NWh8t6pbDyn0WOMCIfRfDQAOGxqbOgJWuxv3Cxw,116
158
+ micropython_stubber-1.24.1.dist-info/LICENSE,sha256=Fx9qrL45ayRXgH6QzttboqZEjKXms0w1t_b_nkOqYCU,1572
159
+ micropython_stubber-1.24.1.dist-info/METADATA,sha256=6Gnlh9EeIuyneLSALgsqwbQFFeQxhvM1cjrOyza-vHs,25020
160
+ micropython_stubber-1.24.1.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
161
+ micropython_stubber-1.24.1.dist-info/RECORD,,
@@ -15,7 +15,7 @@ from mpflash.mpremoteboard import MPRemoteBoard
15
15
 
16
16
 
17
17
  def flash_esp(mcu: MPRemoteBoard, fw_file: Path, *, erase: bool = True) -> Optional[MPRemoteBoard]:
18
- if mcu.port not in ["esp32", "esp8266"] or mcu.board in ["ARDUINO_NANO_ESP32"]:
18
+ if mcu.port not in ["esp32", "esp8266"] or mcu.board.startswith("ARDUINO_"):
19
19
  log.error(f"esptool not supported for {mcu.port} {mcu.board} on {mcu.serialport}")
20
20
  return None
21
21
 
@@ -13,8 +13,8 @@ import libcst as cst
13
13
  from libcst.codemod import CodemodContext, VisitorBasedCodemodCommand
14
14
  from libcst.codemod.visitors import AddImportsVisitor, GatherImportsVisitor, ImportItem
15
15
  from libcst.helpers.module import insert_header_comments
16
- from mpflash.logger import log
17
16
 
17
+ from mpflash.logger import log
18
18
  from stubber.cst_transformer import (
19
19
  MODULE_KEY,
20
20
  AnnoValue,
@@ -23,7 +23,7 @@ from stubber.cst_transformer import (
23
23
  update_module_docstr,
24
24
  )
25
25
 
26
- from .visitors.typevars import AddTypeVarsVisitor, GatherTypeVarsVisitor
26
+ from .visitors.type_helpers import AddTypeHelpers, GatherTypeHelpers
27
27
 
28
28
  Mod_Class_T = TypeVar("Mod_Class_T", cst.Module, cst.ClassDef)
29
29
  """TypeVar for Module or ClassDef that both support overloads"""
@@ -95,7 +95,7 @@ class MergeCommand(VisitorBasedCodemodCommand):
95
95
 
96
96
  self.stub_imports: Dict[str, ImportItem] = {}
97
97
  self.all_imports: List[Union[cst.Import, cst.ImportFrom]] = []
98
- self.typevars = []
98
+ self.type_helpers = []
99
99
  # parse the doc-stub file
100
100
  if self.docstub_source:
101
101
  try:
@@ -107,7 +107,7 @@ class MergeCommand(VisitorBasedCodemodCommand):
107
107
  # create the collectors
108
108
  typing_collector = StubTypingCollector()
109
109
  import_collector = GatherImportsVisitor(context)
110
- typevar_collector = GatherTypeVarsVisitor(context)
110
+ typevar_collector = GatherTypeHelpers(context)
111
111
  # visit the source / doc-stub file with all collectors
112
112
  stub_tree.visit(typing_collector)
113
113
  self.annotations = typing_collector.annotations
@@ -116,9 +116,9 @@ class MergeCommand(VisitorBasedCodemodCommand):
116
116
  stub_tree.visit(import_collector)
117
117
  self.stub_imports = import_collector.symbol_mapping
118
118
  self.all_imports = import_collector.all_imports
119
- # Get typevars
119
+ # Get typevars, type aliasses and ParamSpecs
120
120
  stub_tree.visit(typevar_collector)
121
- self.typevars = typevar_collector.all_typealias_or_vars
121
+ self.type_helpers = typevar_collector.all_typehelpers
122
122
 
123
123
  # ------------------------------------------------------------------------
124
124
 
@@ -177,11 +177,11 @@ class MergeCommand(VisitorBasedCodemodCommand):
177
177
  )
178
178
  # --------------------------------------------------------------------
179
179
  # Add any typevars to the module
180
- if self.typevars:
181
- for tv in self.typevars:
182
- AddTypeVarsVisitor.add_typevar(self.context, tv) # type: ignore
180
+ if self.type_helpers:
181
+ for tv in self.type_helpers:
182
+ AddTypeHelpers.add_typevar(self.context, tv) # type: ignore
183
183
 
184
- atv = AddTypeVarsVisitor(self.context)
184
+ atv = AddTypeHelpers(self.context)
185
185
  updated_node = atv.transform_module(updated_node)
186
186
 
187
187
  # --------------------------------------------------------------------
@@ -0,0 +1,182 @@
1
+ """
2
+ Gather all TypeVar and TypeAlias assignments in a module.
3
+ """
4
+
5
+ from typing import List, Sequence, Tuple, Union
6
+
7
+ import libcst
8
+ import libcst.matchers as m
9
+ from libcst import SimpleStatementLine
10
+ from libcst.codemod._context import CodemodContext
11
+ from libcst.codemod._visitor import ContextAwareTransformer, ContextAwareVisitor
12
+ from libcst.codemod.visitors._add_imports import _skip_first
13
+ from typing_extensions import TypeAlias
14
+
15
+ from mpflash.logger import log
16
+
17
+ TypeHelper: TypeAlias = Union[libcst.Assign, libcst.AnnAssign]
18
+ TypeHelpers: TypeAlias = List[TypeHelper]
19
+ Statement: TypeAlias = Union[libcst.SimpleStatementLine, libcst.BaseCompoundStatement]
20
+
21
+ _mod = libcst.parse_module("") # Debugging aid : _mod.code_for_node(node)
22
+ _code = _mod.code_for_node # Debugging aid : _code(node)
23
+
24
+
25
+ def is_TypeAlias(statement) -> bool:
26
+ "Annotated Assign - Foo:TypeAlias = ..."
27
+ if m.matches(statement, m.SimpleStatementLine()):
28
+ statement = statement.body[0]
29
+ return m.matches(
30
+ statement,
31
+ m.AnnAssign(annotation=m.Annotation(annotation=m.Name(value="TypeAlias"))),
32
+ )
33
+
34
+
35
+ def is_TypeVar(statement):
36
+ "Assing - Foo = Typevar(...)"
37
+ if m.matches(statement, m.SimpleStatementLine()):
38
+ statement = statement.body[0]
39
+ return m.matches(
40
+ statement,
41
+ m.Assign(value=m.Call(func=m.Name(value="TypeVar"))),
42
+ )
43
+
44
+
45
+ def is_ParamSpec(statement):
46
+ "Assign - Foo = ParamSpec(...)"
47
+ if m.matches(statement, m.SimpleStatementLine()):
48
+ statement = statement.body[0]
49
+ return m.matches(
50
+ statement,
51
+ m.Assign(value=m.Call(func=m.Name(value="ParamSpec"))),
52
+ )
53
+
54
+
55
+ def is_import(statement):
56
+ "import - import foo"
57
+ return m.matches(statement, m.SimpleStatementLine(body=[m.ImportFrom() | m.Import()]))
58
+
59
+
60
+ class GatherTypeHelpers(ContextAwareVisitor):
61
+ """
62
+ A class for tracking visited TypeVars and TypeAliases.
63
+ """
64
+
65
+ def __init__(self, context: CodemodContext) -> None:
66
+ super().__init__(context)
67
+ # Track all of the TypeVar, TypeAlias and Paramspec assignments found
68
+ self.all_typehelpers: TypeHelpers = []
69
+
70
+ def visit_Assign(self, node: libcst.Assign) -> None:
71
+ """
72
+ Find all TypeVar assignments in the module.
73
+ format: T = TypeVar("T", int, float, str, bytes, Tuple)
74
+ """
75
+ # is this a TypeVar assignment?
76
+ # needs to be more robust
77
+ if is_TypeVar(node) or is_ParamSpec(node):
78
+ self.all_typehelpers.append(node)
79
+
80
+ def visit_AnnAssign(self, node: libcst.AnnAssign) -> None:
81
+ """ "
82
+ Find all TypeAlias assignments in the module.
83
+ format: T: TypeAlias = str
84
+ """
85
+ if is_TypeAlias(node):
86
+ self.all_typehelpers.append(node)
87
+
88
+
89
+ class AddTypeHelpers(ContextAwareTransformer):
90
+ """
91
+ Visitor loosly based on AddImportsVisitor
92
+ """
93
+
94
+ CONTEXT_KEY = "AddTypeHelpers"
95
+
96
+ def __init__(self, context: CodemodContext) -> None:
97
+ super().__init__(context)
98
+ self.new_typehelpers: TypeHelpers = context.scratch.get(self.CONTEXT_KEY, [])
99
+ self.all_typehelpers: TypeHelpers = []
100
+
101
+ @classmethod
102
+ def add_typevar(cls, context: CodemodContext, node: libcst.Assign):
103
+ new_typehelpers = context.scratch.get(cls.CONTEXT_KEY, [])
104
+ new_typehelpers.append(node)
105
+ context.scratch[cls.CONTEXT_KEY] = new_typehelpers
106
+ # add the typevar to the module
107
+
108
+ def leave_Module(
109
+ self,
110
+ original_node: libcst.Module,
111
+ updated_node: libcst.Module,
112
+ ) -> libcst.Module:
113
+ if not self.new_typehelpers:
114
+ return updated_node
115
+
116
+ # split the module into 3 parts
117
+ # before and after the insertions point , and a list of the TV and TA statements
118
+ (
119
+ statements_before,
120
+ helper_statements,
121
+ statements_after,
122
+ ) = self._split_module(original_node, updated_node)
123
+
124
+ # simpler to compare as text than to compare the nodes -
125
+ existing_targets = [
126
+ helper.body[0].targets[0].target.value # type: ignore
127
+ for helper in helper_statements
128
+ if is_TypeVar(helper) or is_ParamSpec(helper)
129
+ ] + [
130
+ helper.body[0].target.value # type: ignore
131
+ for helper in helper_statements
132
+ if is_TypeAlias(helper)
133
+ ]
134
+ statements_to_add = []
135
+ for new_typehelper in self.new_typehelpers:
136
+ if isinstance(new_typehelper, libcst.AnnAssign):
137
+ if new_typehelper.target.value not in existing_targets: # type: ignore
138
+ statements_to_add.append(SimpleStatementLine(body=[new_typehelper]))
139
+ elif isinstance(new_typehelper, libcst.Assign):
140
+ if new_typehelper.targets[0].target.value not in existing_targets: # type: ignore
141
+ statements_to_add.append(SimpleStatementLine(body=[new_typehelper]))
142
+
143
+ body = (
144
+ *statements_before,
145
+ *statements_to_add,
146
+ *statements_after,
147
+ )
148
+
149
+ return updated_node.with_changes(body=body)
150
+
151
+ def _split_module(
152
+ self,
153
+ orig_module: libcst.Module,
154
+ updated_module: libcst.Module,
155
+ ) -> Tuple[Sequence[Statement], Sequence[libcst.SimpleStatementLine], Sequence[Statement]]:
156
+ """
157
+ Split the module into 3 parts:
158
+ - before any TypeAlias, TypeVar or ParamSpec statements
159
+ - the TypeAlias and TypeVar statements
160
+ - the rest of the module after the TypeAlias and TypeVar statements
161
+ """
162
+ last_import = first_typehelper = last_typehelper = -1
163
+ start = 0
164
+ if _skip_first(orig_module):
165
+ start = 1
166
+
167
+ for i, statement in enumerate(orig_module.body[start:]):
168
+ if is_import(statement):
169
+ last_import = i + start
170
+ continue
171
+ if is_TypeVar(statement) or is_TypeAlias(statement) or is_ParamSpec(statement):
172
+ if first_typehelper == -1:
173
+ first_typehelper = i + start
174
+ last_typehelper = i + start
175
+ # insert as high as possible, but after the last import and last TypeVar/TypeAlias statement
176
+ insert_after = max(start, last_import + 1, last_typehelper + 1)
177
+ assert insert_after != -1, "insert_after must be != -1"
178
+ #
179
+ before = list(updated_module.body[:insert_after])
180
+ after = list(updated_module.body[insert_after:])
181
+ helper_statements: Sequence[libcst.SimpleStatementLine] = list(updated_module.body[first_typehelper : last_typehelper + 1]) # type: ignore
182
+ return (before, helper_statements, after)
@@ -1,200 +0,0 @@
1
- """
2
- Gather all TypeVar and TypeAlias assignments in a module.
3
- """
4
-
5
- from typing import List, Tuple, Union
6
-
7
- import libcst
8
- import libcst.matchers as m
9
- from libcst import SimpleStatementLine
10
- from libcst.codemod._context import CodemodContext
11
- from libcst.codemod._visitor import ContextAwareTransformer, ContextAwareVisitor
12
- from libcst.codemod.visitors._add_imports import _skip_first
13
- from mpflash.logger import log
14
-
15
- _mod = libcst.parse_module("") # Debugging aid : _mod.code_for_node(node)
16
- _code = _mod.code_for_node # Debugging aid : _code(node)
17
-
18
-
19
- class GatherTypeVarsVisitor(ContextAwareVisitor):
20
- """
21
- A class for tracking visited TypeVars and TypeAliases.
22
- """
23
-
24
- def __init__(self, context: CodemodContext) -> None:
25
- super().__init__(context)
26
- # Track all of the TypeVar assignments found in this transform
27
- self.all_typealias_or_vars: List[Union[libcst.Assign, libcst.AnnAssign]] = []
28
-
29
- def visit_Assign(self, node: libcst.Assign) -> None:
30
- """
31
- Find all TypeVar assignments in the module.
32
- format: T = TypeVar("T", int, float, str, bytes, Tuple)
33
- """
34
- # is this a TypeVar assignment?
35
- # needs to be more robust
36
- if isinstance(node.value, libcst.Call) and node.value.func.value == "TypeVar": # type: ignore
37
- self.all_typealias_or_vars.append(node)
38
-
39
- def visit_AnnAssign(self, node: libcst.AnnAssign) -> None:
40
- """ "
41
- Find all TypeAlias assignments in the module.
42
- format: T: TypeAlias = str
43
- """
44
- if (
45
- isinstance(node.annotation.annotation, libcst.Name)
46
- and node.annotation.annotation.value == "TypeAlias"
47
- ):
48
- self.all_typealias_or_vars.append(node)
49
-
50
-
51
- def is_TypeAlias(statement) -> bool:
52
- "Just the body of a simple statement" ""
53
- return m.matches(
54
- statement,
55
- m.AnnAssign(annotation=m.Annotation(annotation=m.Name(value="TypeAlias"))),
56
- )
57
-
58
-
59
- def is_TypeVar(statement):
60
- "Just the body of a simple statement" ""
61
- r = m.matches(
62
- statement,
63
- m.Assign(value=m.Call(func=m.Name(value="TypeVar"))),
64
- )
65
- # m.SimpleStatementLine(body=[m.Assign(value=m.Call(func=m.Name(value="TypeVar")))]),
66
- return r
67
-
68
-
69
- class AddTypeVarsVisitor(ContextAwareTransformer):
70
- """
71
- Visitor loosly based on AddImportsVisitor
72
- """
73
-
74
- CONTEXT_KEY = "AddTypeVarsVisitor"
75
-
76
- def __init__(self, context: CodemodContext) -> None:
77
- super().__init__(context)
78
- self.new_typealias_or_vars: List[Union[libcst.Assign, libcst.AnnAssign]] = (
79
- context.scratch.get(self.CONTEXT_KEY, [])
80
- )
81
-
82
- self.all_typealias_or_vars: List[Union[libcst.Assign, libcst.AnnAssign]] = []
83
-
84
- @classmethod
85
- def add_typevar(cls, context: CodemodContext, node: libcst.Assign):
86
- new_typealias_or_vars = context.scratch.get(cls.CONTEXT_KEY, [])
87
- new_typealias_or_vars.append(node)
88
- context.scratch[cls.CONTEXT_KEY] = new_typealias_or_vars
89
- # add the typevar to the module
90
-
91
- def leave_Module(
92
- self,
93
- original_node: libcst.Module,
94
- updated_node: libcst.Module,
95
- ) -> libcst.Module:
96
-
97
- if not self.new_typealias_or_vars:
98
- return updated_node
99
-
100
- # split the module into 3 parts
101
- # before and after the insertions point , and a list of the TV and TA statements
102
- (
103
- statements_before,
104
- statements_after,
105
- tv_ta_statements,
106
- ) = self._split_module(original_node, updated_node)
107
-
108
- # TODO: avoid duplication of TypeVars and TypeAliases
109
- statements_to_add = []
110
- for new_tvta in self.new_typealias_or_vars:
111
- existing = False
112
- for existing_line in tv_ta_statements:
113
- try:
114
- existing_tv = existing_line.body[0] # type: ignore
115
- except (TypeError, IndexError):
116
- # catch 'SimpleStatementLine' object is not subscriptable when the statement is not a simple statement
117
- log.error("TypeVar or TypeAlias statement is not a simple statement")
118
- continue
119
-
120
- # same type and same target?
121
- if (
122
- is_TypeAlias(new_tvta)
123
- and is_TypeAlias(existing_tv)
124
- and new_tvta.target.value == existing_tv.target.value # type: ignore
125
- ):
126
- existing = True
127
- break
128
-
129
- # same type and same targets?
130
- if (
131
- is_TypeVar(new_tvta)
132
- and is_TypeVar(existing_tv)
133
- and new_tvta.targets[0].children[0].value == existing_tv.targets[0].children[0].value # type: ignore
134
- ):
135
- existing = True
136
- break
137
-
138
- if not existing:
139
- statements_to_add.append(SimpleStatementLine(body=[new_tvta]))
140
-
141
- body = (
142
- *statements_before,
143
- *statements_to_add,
144
- *statements_after,
145
- )
146
-
147
- return updated_node.with_changes(body=body)
148
-
149
- def _split_module(
150
- self,
151
- orig_module: libcst.Module,
152
- updated_module: libcst.Module,
153
- ) -> Tuple[
154
- List[Union[libcst.SimpleStatementLine, libcst.BaseCompoundStatement]],
155
- List[Union[libcst.SimpleStatementLine, libcst.BaseCompoundStatement]],
156
- List[Union[libcst.SimpleStatementLine, libcst.BaseCompoundStatement]],
157
- ]:
158
- """
159
- Split the module into 3 parts:
160
- - before any TypeAlias or TypeVar statements
161
- - the TypeAlias and TypeVar statements
162
- - the rest of the module after the TypeAlias and TypeVar statements
163
- """
164
- last_import = first_tv_ta = last_tv_ta = -1
165
- start = 0
166
- if _skip_first(orig_module):
167
- start = 1
168
-
169
- for i, statement in enumerate(orig_module.body[start:]):
170
- # todo: optimize to avoid multiple parses
171
- is_imp = m.matches(
172
- statement, m.SimpleStatementLine(body=[m.ImportFrom() | m.Import()])
173
- )
174
- if is_imp:
175
- last_import = i + start
176
- is_ta = m.matches(
177
- statement,
178
- m.SimpleStatementLine(
179
- body=[
180
- m.AnnAssign(annotation=m.Annotation(annotation=m.Name(value="TypeAlias")))
181
- ]
182
- ),
183
- )
184
- is_tv = m.matches(
185
- statement,
186
- m.SimpleStatementLine(body=[m.Assign(value=m.Call(func=m.Name(value="TypeVar")))]),
187
- )
188
- if is_tv or is_ta:
189
- if first_tv_ta == -1:
190
- first_tv_ta = i + start
191
- last_tv_ta = i + start
192
- # insert as high as possible, but after the last import and last TypeVar/TypeAlias statement
193
- insert_after = max(start, last_import + 1, last_tv_ta + 1)
194
- assert insert_after != -1, "insert_after must be != -1"
195
- #
196
- first = list(updated_module.body[:insert_after])
197
- last = list(updated_module.body[insert_after:])
198
- ta_statements = list(updated_module.body[first_tv_ta : last_tv_ta + 1])
199
-
200
- return (first, last, ta_statements)