Skip to content

Commit 412ed5a

Browse files
committed
tools: Fix update-meson type errors
1 parent edd2ee3 commit 412ed5a

1 file changed

Lines changed: 73 additions & 38 deletions

File tree

tools/update-meson.py

Lines changed: 73 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import os
1212
from argparse import Namespace
1313
from pathlib import Path
14+
from typing import Any, cast
1415

1516
from mesonbuild import mlog
1617
from mesonbuild.ast import (
@@ -25,6 +26,7 @@
2526
AssignmentNode,
2627
BaseNode,
2728
DictNode,
29+
IdNode,
2830
SymbolNode,
2931
)
3032
from mesonbuild.rewriter import (
@@ -47,7 +49,7 @@
4749
class AstPython(AstVisitor):
4850
install_sources_calls: list[MethodNode] = []
4951
extension_data: list[AssignmentNode] = []
50-
doc_sources: list[MethodNode] = []
52+
doc_sources: list[AssignmentNode] = []
5153

5254
def visit_MethodNode(self, node: MethodNode) -> None:
5355
if node.name.value == "install_sources":
@@ -63,8 +65,8 @@ def visit_AssignmentNode(self, node: AssignmentNode) -> None:
6365

6466

6567
# Utility function to get a list of the sources from a node
66-
def arg_list_from_node(n):
67-
args = []
68+
def arg_list_from_node(n: BaseNode) -> list[BaseNode]:
69+
args: list[BaseNode] = []
6870
if isinstance(n, FunctionNode) or isinstance(n, MethodNode):
6971
args = list(n.args.arguments)
7072
# if 'func_name' in n and n.func_name.value in BUILD_TARGET_FUNCTIONS:
@@ -76,34 +78,45 @@ def arg_list_from_node(n):
7678
return args
7779

7880

81+
def _token(tid: str, filename: str, value: str) -> Token[str]:
82+
return Token(tid, filename, 0, 0, 0, (0, 0), value)
83+
84+
7985
def _symbol(val: str) -> SymbolNode:
80-
return SymbolNode(Token("", "", 0, 0, 0, (0, 0), val))
86+
return SymbolNode(_token("", "", val))
87+
8188

89+
def _id(val: str) -> IdNode:
90+
return IdNode(_token("id", "", val))
8291

83-
def update_python_sources(self: Rewriter, visitor: AstPython):
92+
93+
def update_python_sources(self: Rewriter, visitor: AstPython) -> None:
8494
for target in visitor.install_sources_calls:
8595
# Generate the current source list
86-
src_list: list[str] = []
96+
python_sources: list[str] = []
8797
for arg in arg_list_from_node(target):
8898
if isinstance(arg, StringNode):
89-
src_list += [arg.value]
99+
python_sources += [arg.value]
90100

91101
folder = Path(target.filename).parent
92102
python_files = sorted(
93-
list(folder.glob("*.py")) + list(folder.glob('*.pxd')) + list(folder.glob('*.pyx')) + list(folder.glob('*.pyi'))
103+
list(folder.glob("*.py"))
104+
+ list(folder.glob('*.pxd'))
105+
+ list(folder.glob('*.pyx'))
106+
+ list(folder.glob('*.pyi'))
94107
) # + list(folder.glob('*.pxd')) + list(folder.glob('*.h')))
95108

96109
to_append: list[StringNode] = []
97110
for file in python_files:
98111
file_name = file.name
99-
if file_name in src_list:
112+
if file_name in python_sources:
100113
continue
101-
token = Token("string", target.filename, 0, 0, 0, None, file_name)
114+
token = _token("string", target.filename, file_name)
102115
to_append += [StringNode(token)]
103116

104117
# Get all deleted files
105118
to_remove = []
106-
for src in src_list:
119+
for src in python_sources:
107120
if not folder.joinpath(src).exists():
108121
to_remove += [src]
109122

@@ -118,7 +131,7 @@ def update_python_sources(self: Rewriter, visitor: AstPython):
118131
if not (isinstance(arg, StringNode) and arg.value in to_remove)
119132
]
120133
+ to_append,
121-
key=lambda x: x.value,
134+
key=lambda x: cast("StringNode", x).value,
122135
)
123136

124137
# Mark the node as modified
@@ -129,17 +142,24 @@ def update_python_sources(self: Rewriter, visitor: AstPython):
129142
for target in visitor.extension_data:
130143
folder = Path(target.filename).parent
131144
# Generate the current source dict
132-
src_list: dict[str, BaseNode] = {}
145+
extension_sources_by_name: dict[str, BaseNode] = {}
133146
if isinstance(target.value, DictNode):
134-
src_list.update({k.value: v for k, v in target.value.args.kwargs.items()})
147+
extension_sources_by_name.update(
148+
{
149+
cast("StringNode", key).value: value
150+
for key, value in target.value.args.kwargs.items()
151+
}
152+
)
135153
ext_data.setdefault(folder, [])
136-
ext_data[folder] += src_list.keys()
154+
ext_data[folder] += extension_sources_by_name.keys()
137155

138156
for target in visitor.extension_data:
139157
if target.var_name.value != "extension_data":
140158
continue
159+
if not isinstance(target.value, DictNode):
160+
continue
141161
folder = Path(target.filename).parent
142-
src_list = ext_data[folder]
162+
extension_sources = ext_data[folder]
143163

144164
cython_files = sorted(folder.glob("*.pyx"))
145165
# Some cython files are compiled in a special way, so we don't want to add them
@@ -152,20 +172,18 @@ def update_python_sources(self: Rewriter, visitor: AstPython):
152172
# Add all cython files that are not in the source list
153173
for file in cython_files:
154174
file_name = file.stem
155-
if file_name in src_list:
175+
if file_name in extension_sources:
156176
continue
157-
token = Token("string", target.filename, 0, 0, 0, None, file_name)
158-
arg = ArgumentNode(Token("", target.filename, 0, 0, 0, None, "[]"))
159-
arg.append(
160-
StringNode(Token("string", target.filename, 0, 0, 0, None, file.name))
161-
)
162-
func = FunctionNode(_symbol("files"), _symbol("("), arg, _symbol(")"))
177+
token = _token("string", target.filename, file_name)
178+
arg = ArgumentNode(_token("", target.filename, "[]"))
179+
arg.append(StringNode(_token("string", target.filename, file.name)))
180+
func = FunctionNode(_id("files"), _symbol("("), arg, _symbol(")"))
163181
target.value.args.kwargs.update({StringNode(token): func})
164182
if target not in self.modified_nodes:
165183
self.modified_nodes += [target]
166184

167185

168-
def update_doc_sources(self: Rewriter, visitor: AstPython):
186+
def update_doc_sources(self: Rewriter, visitor: AstPython) -> None:
169187
doc_sources: dict[Path, list[str]] = {}
170188
ignored_files = {'bootstrap', 'Makefile', 'meson.build'}
171189
ignored_folders = {'__pycache__', 'sage'}
@@ -176,11 +194,15 @@ def update_doc_sources(self: Rewriter, visitor: AstPython):
176194
if isinstance(target.value, ArrayNode):
177195
src_list.extend(target.value.args.arguments)
178196
doc_sources.setdefault(folder, [])
179-
doc_sources[folder] += [x.value for x in src_list]
197+
doc_sources[folder] += [
198+
source.value for source in src_list if isinstance(source, StringNode)
199+
]
180200

181201
for target in visitor.doc_sources:
182202
if target.var_name.value != "doc_sources":
183203
continue
204+
if not isinstance(target.value, ArrayNode):
205+
continue
184206
folder = Path(target.filename).parent
185207
existing_sources: list[str] = doc_sources[folder]
186208
# Add all files that are not in the source list
@@ -191,15 +213,22 @@ def update_doc_sources(self: Rewriter, visitor: AstPython):
191213
if file_name in ignored_files or file.suffix == ".pyc":
192214
continue
193215
existing_sources.append(file_name)
194-
token = Token("string", target.filename, 0, 0, 0, None, file_name)
216+
token = _token("string", target.filename, file_name)
195217
target.value.args.arguments.append(StringNode(token))
196218
if target not in self.modified_nodes:
197219
self.modified_nodes += [target]
198220
# Remove all files that are no longer existing
199221
for file in existing_sources:
200222
if not (folder / file).exists():
201223
existing_sources.remove(file)
202-
token = next((x for x in target.value.args.arguments if getattr(x, "value", None) == file), None)
224+
token = next(
225+
(
226+
x
227+
for x in target.value.args.arguments
228+
if getattr(x, "value", None) == file
229+
),
230+
None,
231+
)
203232
if token is not None:
204233
target.value.args.arguments.remove(token)
205234
if target not in self.modified_nodes:
@@ -208,7 +237,7 @@ def update_doc_sources(self: Rewriter, visitor: AstPython):
208237
# Add all missing meson files in the src/doc folder
209238
doc_folder = Path(options.sourcedir) / "src" / "doc"
210239
# Delete all totally empty folders as pre-processing step
211-
for folder, dirs, files in doc_folder.walk(top_down = False):
240+
for folder, dirs, files in doc_folder.walk(top_down=False):
212241
if not dirs and not files:
213242
folder.rmdir()
214243

@@ -241,7 +270,8 @@ def update_doc_sources(self: Rewriter, visitor: AstPython):
241270
continue
242271
f.write(f"subdir('{dir}')\n")
243272

244-
def apply_changes(self: Rewriter):
273+
274+
def apply_changes(self: Rewriter) -> None:
245275
assert all(
246276
hasattr(x, "lineno") and hasattr(x, "colno") and hasattr(x, "filename")
247277
for x in self.modified_nodes
@@ -262,7 +292,12 @@ def apply_changes(self: Rewriter):
262292
work_nodes = [{"node": x, "action": "modify"} for x in self.modified_nodes]
263293
work_nodes += [{"node": x, "action": "rm"} for x in self.to_remove_nodes]
264294
work_nodes = sorted(
265-
work_nodes, key=lambda x: (x["node"].lineno, x["node"].colno), reverse=True
295+
work_nodes,
296+
key=lambda x: (
297+
cast("BaseNode", x["node"]).lineno,
298+
cast("BaseNode", x["node"]).colno,
299+
),
300+
reverse=True,
266301
)
267302
work_nodes += [{"node": x, "action": "add"} for x in self.to_add_nodes]
268303

@@ -272,19 +307,19 @@ def apply_changes(self: Rewriter):
272307
new_data = ""
273308
if i["action"] == "modify" or i["action"] == "add":
274309
printer = AstPrinter()
275-
i["node"].accept(printer)
310+
cast("BaseNode", i["node"]).accept(printer)
276311
printer.post_process()
277312
new_data = printer.result.strip()
278313
data = {
279-
"file": i["node"].filename,
314+
"file": cast("BaseNode", i["node"]).filename,
280315
"str": new_data,
281316
"node": i["node"],
282317
"action": i["action"],
283318
}
284319
str_list += [data]
285320

286321
# Load build files
287-
files = {}
322+
files: dict[str, Any] = {}
288323
for i in str_list:
289324
if i["file"] in files:
290325
continue
@@ -308,7 +343,7 @@ def apply_changes(self: Rewriter):
308343
files[i["file"]] = {"path": fpath, "raw": fdata, "offsets": line_offsets}
309344

310345
# Replace in source code
311-
def remove_node(i):
346+
def remove_node(i: dict[str, Any]) -> None:
312347
offsets = files[i["file"]]["offsets"]
313348
raw = files[i["file"]]["raw"]
314349
node = i["node"]
@@ -357,15 +392,15 @@ def remove_node(i):
357392
# Monkey patch the apply_changes method until https://github.com/mesonbuild/meson/pull/12899 is merged
358393
Rewriter.apply_changes = apply_changes
359394
# Monkey patch the update_python_sources method until this is upstreamed
360-
Rewriter.process_update_python_sources = update_python_sources
361-
Rewriter.process_update_doc_sources = update_doc_sources
395+
setattr(Rewriter, "process_update_python_sources", update_python_sources)
396+
setattr(Rewriter, "process_update_doc_sources", update_doc_sources)
362397

363398
rewriter = Rewriter(options.sourcedir)
364399
visitor = AstPython()
365400
rewriter.interpreter.visitors += [visitor]
366401
rewriter.analyze_meson()
367-
rewriter.process_update_python_sources(visitor)
368-
rewriter.process_update_doc_sources(visitor)
402+
update_python_sources(rewriter, visitor)
403+
update_doc_sources(rewriter, visitor)
369404
rewriter.apply_changes()
370405
rewriter.print_info()
371406

0 commit comments

Comments
 (0)