Skip to content

Commit 689768e

Browse files
committed
Address code review
1 parent fd4743a commit 689768e

File tree

11 files changed

+273
-170
lines changed

11 files changed

+273
-170
lines changed

.github/workflows/mypy.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ jobs:
3535
with:
3636
python-version: "3.x"
3737
cache: pip
38-
cache-dependency-path: Tools/clinic/requirements-dev.txt
39-
- run: pip install -r Tools/clinic/requirements-dev.txt
38+
cache-dependency-path: Tools/requirements-dev.txt
39+
- run: pip install -r Tools/requirements-dev.txt
4040
- run: mypy --config-file Tools/clinic/mypy.ini
4141

4242
mypy-cases-generator:
@@ -49,6 +49,8 @@ jobs:
4949
with:
5050
python-version: "3.x"
5151
cache: pip
52-
cache-dependency-path: Tools/cases_generator/requirements-dev.txt
53-
- run: pip install -r Tools/cases_generator/requirements-dev.txt
52+
cache-dependency-path: Tools/requirements-dev.txt
53+
- run: pip install -r Tools/requirements-dev.txt
54+
- name: Lint with black
55+
run: black Tools/cases_generator
5456
- run: mypy --config-file Tools/cases_generator/mypy.ini

Tools/cases_generator/analysis.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ def parse_file(self, filename: str, instrs_idx: dict[str, int]) -> None:
171171
case parsing.Pseudo(name):
172172
self.pseudos[name] = thing
173173
self.everything.append(thing)
174+
case _:
175+
typing.assert_never(thing)
174176
if not psr.eof():
175177
raise psr.make_syntax_error(f"Extra stuff at the end of {filename}")
176178

@@ -402,4 +404,6 @@ def check_macro_components(
402404
components.append(self.instrs[name])
403405
case parsing.CacheEffect():
404406
components.append(uop)
407+
case _:
408+
typing.assert_never(uop)
405409
return components

Tools/cases_generator/flags.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __post_init__(self) -> None:
2020
self.bitmask = {name: (1 << i) for i, name in enumerate(self.names())}
2121

2222
@staticmethod
23-
def fromInstruction(instr: parsing.Node) -> 'InstructionFlags':
23+
def fromInstruction(instr: parsing.Node) -> "InstructionFlags":
2424

2525
has_free = (
2626
variable_used(instr, "PyCell_New")
@@ -41,15 +41,15 @@ def fromInstruction(instr: parsing.Node) -> 'InstructionFlags':
4141
)
4242

4343
@staticmethod
44-
def newEmpty() -> 'InstructionFlags':
44+
def newEmpty() -> "InstructionFlags":
4545
return InstructionFlags(False, False, False, False, False, False)
4646

4747
def add(self, other: "InstructionFlags") -> None:
4848
for name, value in dataclasses.asdict(other).items():
4949
if value:
5050
setattr(self, name, value)
5151

52-
def names(self, value: bool|None = None) -> list[str]:
52+
def names(self, value: bool | None = None) -> list[str]:
5353
if value is None:
5454
return list(dataclasses.asdict(self).keys())
5555
return [n for n, v in dataclasses.asdict(self).items() if v == value]
@@ -90,9 +90,9 @@ def variable_used_unspecialized(node: parsing.Node, name: str) -> bool:
9090
text = "".join(token.text.split())
9191
# TODO: Handle nested #if
9292
if text == "#if":
93-
if (
94-
i + 1 < len(node.tokens)
95-
and node.tokens[i + 1].text in ("ENABLE_SPECIALIZATION", "TIER_ONE")
93+
if i + 1 < len(node.tokens) and node.tokens[i + 1].text in (
94+
"ENABLE_SPECIALIZATION",
95+
"TIER_ONE",
9696
):
9797
skipping = True
9898
elif text in ("#else", "#endif"):

Tools/cases_generator/formatting.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import collections
12
import contextlib
23
import re
34
import typing
@@ -58,13 +59,13 @@ def reset_lineno(self) -> None:
5859
self.set_lineno(self.lineno + 1, self.filename)
5960

6061
@contextlib.contextmanager
61-
def indent(self) -> typing.Iterator[None]:
62+
def indent(self) -> collections.abc.Iterator[None]:
6263
self.prefix += " "
6364
yield
6465
self.prefix = self.prefix[:-4]
6566

6667
@contextlib.contextmanager
67-
def block(self, head: str, tail: str = "") -> typing.Iterator[None]:
68+
def block(self, head: str, tail: str = "") -> collections.abc.Iterator[None]:
6869
if head:
6970
self.emit(head + " {")
7071
else:

Tools/cases_generator/generate_cases.py

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,10 @@
7979
"STORE_FAST",
8080
"STORE_FAST_MAYBE_NULL",
8181
"COPY",
82-
8382
# Arithmetic
8483
"_BINARY_OP_MULTIPLY_INT",
8584
"_BINARY_OP_ADD_INT",
8685
"_BINARY_OP_SUBTRACT_INT",
87-
8886
}
8987

9088
arg_parser = argparse.ArgumentParser(
@@ -143,6 +141,7 @@
143141
default=DEFAULT_ABSTRACT_INTERPRETER_OUTPUT,
144142
)
145143

144+
146145
class Generator(Analyzer):
147146
def get_stack_effect_info(
148147
self, thing: parsing.InstDef | parsing.Macro | parsing.Pseudo
@@ -183,10 +182,14 @@ def effect_str(effects: list[StackEffect]) -> str:
183182
target_popped = effect_str(target_instr.input_effects)
184183
target_pushed = effect_str(target_instr.output_effects)
185184
popped, pushed = target_popped, target_pushed
185+
case _:
186+
typing.assert_never(thing)
186187
return instr, popped, pushed
187188

188189
@contextlib.contextmanager
189-
def metadata_item(self, signature: str, open: str, close: str) -> typing.Iterator[None]:
190+
def metadata_item(
191+
self, signature: str, open: str, close: str
192+
) -> typing.Iterator[None]:
190193
self.out.emit("")
191194
self.out.emit(f"extern {signature};")
192195
self.out.emit("#ifdef NEED_OPCODE_METADATA")
@@ -211,7 +214,9 @@ def write_function(
211214
) -> None:
212215

213216
with self.metadata_item(
214-
f"int _PyOpcode_num_{direction}(int opcode, int oparg, bool jump)", "", ""
217+
f"int _PyOpcode_num_{direction}(int opcode, int oparg, bool jump)",
218+
"",
219+
"",
215220
):
216221
with self.out.block("switch(opcode)"):
217222
for instr, effect in data:
@@ -249,10 +254,11 @@ def assign_opcode_ids(self) -> None:
249254

250255
for instr in itertools.chain(
251256
[instr for instr in self.instrs.values() if instr.kind != "op"],
252-
self.macro_instrs.values()):
257+
self.macro_instrs.values(),
258+
):
253259
assert isinstance(instr, (Instruction, MacroInstruction, PseudoInstruction))
254260
name = instr.name
255-
if name.startswith('INSTRUMENTED_'):
261+
if name.startswith("INSTRUMENTED_"):
256262
instrumented_ops.append(name)
257263
else:
258264
ops.append((instr.instr_flags.HAS_ARG_FLAG, name))
@@ -261,13 +267,13 @@ def assign_opcode_ids(self) -> None:
261267
# rather than bytecodes.c, so we need to add it explicitly
262268
# here (at least until we add something to bytecodes.c to
263269
# declare external instructions).
264-
instrumented_ops.append('INSTRUMENTED_LINE')
270+
instrumented_ops.append("INSTRUMENTED_LINE")
265271

266272
# assert lists are unique
267273
assert len(set(ops)) == len(ops)
268274
assert len(set(instrumented_ops)) == len(instrumented_ops)
269275

270-
opname: list[str|None] = [None] * 512
276+
opname: list[str | None] = [None] * 512
271277
opmap: dict[str, int] = {}
272278
markers: dict[str, int] = {}
273279

@@ -278,16 +284,15 @@ def map_op(op: int, name: str) -> None:
278284
opname[op] = name
279285
opmap[name] = op
280286

281-
282287
# 0 is reserved for cache entries. This helps debugging.
283-
map_op(0, 'CACHE')
288+
map_op(0, "CACHE")
284289

285290
# 17 is reserved as it is the initial value for the specializing counter.
286291
# This helps catch cases where we attempt to execute a cache.
287-
map_op(17, 'RESERVED')
292+
map_op(17, "RESERVED")
288293

289294
# 166 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py
290-
map_op(166, 'RESUME')
295+
map_op(166, "RESUME")
291296

292297
next_opcode = 1
293298

@@ -299,13 +304,13 @@ def map_op(op: int, name: str) -> None:
299304
assert next_opcode < 255
300305
map_op(next_opcode, name)
301306

302-
if has_arg and 'HAVE_ARGUMENT' not in markers:
303-
markers['HAVE_ARGUMENT'] = next_opcode
307+
if has_arg and "HAVE_ARGUMENT" not in markers:
308+
markers["HAVE_ARGUMENT"] = next_opcode
304309

305310
# Instrumented opcodes are at the end of the valid range
306311
min_instrumented = 254 - (len(instrumented_ops) - 1)
307312
assert next_opcode <= min_instrumented
308-
markers['MIN_INSTRUMENTED_OPCODE'] = min_instrumented
313+
markers["MIN_INSTRUMENTED_OPCODE"] = min_instrumented
309314
for i, op in enumerate(instrumented_ops):
310315
map_op(min_instrumented + i, op)
311316

@@ -317,7 +322,9 @@ def map_op(op: int, name: str) -> None:
317322
self.opmap = opmap
318323
self.markers = markers
319324

320-
def write_opcode_ids(self, opcode_ids_h_filename: str, opcode_targets_filename: str) -> None:
325+
def write_opcode_ids(
326+
self, opcode_ids_h_filename: str, opcode_targets_filename: str
327+
) -> None:
321328
"""Write header file that defined the opcode IDs"""
322329

323330
with open(opcode_ids_h_filename, "w") as f:
@@ -330,7 +337,7 @@ def write_opcode_ids(self, opcode_ids_h_filename: str, opcode_targets_filename:
330337
self.out.emit("#ifndef Py_OPCODE_IDS_H")
331338
self.out.emit("#define Py_OPCODE_IDS_H")
332339
self.out.emit("#ifdef __cplusplus")
333-
self.out.emit("extern \"C\" {")
340+
self.out.emit('extern "C" {')
334341
self.out.emit("#endif")
335342
self.out.emit("")
336343
self.out.emit("/* Instruction opcodes for compiled code */")
@@ -363,7 +370,6 @@ def define(name: str, opcode: int) -> None:
363370
targets[op] = f"TARGET_{name}"
364371
f.write(",\n".join([f" &&{s}" for s in targets]))
365372

366-
367373
def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> None:
368374
"""Write instruction metadata to output file."""
369375

@@ -458,7 +464,7 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
458464
"const struct opcode_metadata "
459465
"_PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE]",
460466
"=",
461-
";"
467+
";",
462468
):
463469
# Write metadata for each instruction
464470
for thing in self.everything:
@@ -471,13 +477,15 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
471477
case parsing.Macro():
472478
self.write_metadata_for_macro(self.macro_instrs[thing.name])
473479
case parsing.Pseudo():
474-
self.write_metadata_for_pseudo(self.pseudo_instrs[thing.name])
480+
self.write_metadata_for_pseudo(
481+
self.pseudo_instrs[thing.name]
482+
)
475483

476484
with self.metadata_item(
477485
"const struct opcode_macro_expansion "
478486
"_PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE]",
479487
"=",
480-
";"
488+
";",
481489
):
482490
# Write macro expansion for each non-pseudo instruction
483491
for thing in self.everything:
@@ -514,7 +522,9 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
514522
self.write_uop_items(lambda name, counter: f'[{name}] = "{name}",')
515523

516524
with self.metadata_item(
517-
f"const char *const _PyOpcode_OpName[{1 + max(self.opmap.values())}]", "=", ";"
525+
f"const char *const _PyOpcode_OpName[{1 + max(self.opmap.values())}]",
526+
"=",
527+
";",
518528
):
519529
for name in self.opmap:
520530
self.out.emit(f'[{name}] = "{name}",')
@@ -527,11 +537,9 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
527537
for m in family.members:
528538
deoptcodes[m] = name
529539
# special case:
530-
deoptcodes['BINARY_OP_INPLACE_ADD_UNICODE'] = 'BINARY_OP'
540+
deoptcodes["BINARY_OP_INPLACE_ADD_UNICODE"] = "BINARY_OP"
531541

532-
with self.metadata_item(
533-
f"const uint8_t _PyOpcode_Deopt[256]", "=", ";"
534-
):
542+
with self.metadata_item(f"const uint8_t _PyOpcode_Deopt[256]", "=", ";"):
535543
for opt, deopt in sorted(deoptcodes.items()):
536544
self.out.emit(f"[{opt}] = {deopt},")
537545

@@ -589,10 +597,9 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
589597
if name not in specialized_ops:
590598
self.out.emit(f"'{name}': {op},")
591599

592-
for name in ['MIN_INSTRUMENTED_OPCODE', 'HAVE_ARGUMENT']:
600+
for name in ["MIN_INSTRUMENTED_OPCODE", "HAVE_ARGUMENT"]:
593601
self.out.emit(f"{name} = {self.markers[name]}")
594602

595-
596603
def write_pseudo_instrs(self) -> None:
597604
"""Write the IS_PSEUDO_INSTR macro"""
598605
self.out.emit("\n\n#define IS_PSEUDO_INSTR(OP) ( \\")
@@ -815,7 +822,10 @@ def write_abstract_interpreter_instructions(
815822
pass
816823
case parsing.InstDef():
817824
instr = AbstractInstruction(self.instrs[thing.name].inst)
818-
if instr.is_viable_uop() and instr.name not in SPECIALLY_HANDLED_ABSTRACT_INSTR:
825+
if (
826+
instr.is_viable_uop()
827+
and instr.name not in SPECIALLY_HANDLED_ABSTRACT_INSTR
828+
):
819829
self.out.emit("")
820830
with self.out.block(f"case {thing.name}:"):
821831
instr.write(self.out, tier=TIER_TWO)
@@ -878,8 +888,9 @@ def main() -> None:
878888
a.write_opcode_ids(args.opcode_ids_h, args.opcode_targets_h)
879889
a.write_metadata(args.metadata, args.pymetadata)
880890
a.write_executor_instructions(args.executor_cases, args.emit_line_directives)
881-
a.write_abstract_interpreter_instructions(args.abstract_interpreter_cases,
882-
args.emit_line_directives)
891+
a.write_abstract_interpreter_instructions(
892+
args.abstract_interpreter_cases, args.emit_line_directives
893+
)
883894

884895

885896
if __name__ == "__main__":

0 commit comments

Comments
 (0)