Skip to content

Commit e6b5949

Browse files
authored
Avoid mutating the AST when processing register calls (#10779)
Instead of modifying dec.decorators directly, copy it and only modify the copied version. That prevents us from modifying the AST in mypyc, which we should avoid according to #10753 (comment).
1 parent 53836bd commit e6b5949

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

mypyc/irbuild/prebuildvisitor.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,25 @@ def visit_decorator(self, dec: Decorator) -> None:
7070
# Property setters are not treated as decorated methods.
7171
self.prop_setters.add(dec.func)
7272
else:
73+
decorators_to_store = dec.decorators.copy()
7374
removed: List[int] = []
74-
for i, d in enumerate(dec.decorators):
75+
for i, d in enumerate(decorators_to_store):
7576
impl = get_singledispatch_register_call_info(d, dec.func)
7677
if impl is not None:
7778
self.singledispatch_impls[impl.singledispatch_func].append(
7879
(impl.dispatch_type, dec.func))
7980
removed.append(i)
81+
# calling register on a function that tries to dispatch based on type annotations
82+
# raises a TypeError because compiled functions don't have an __annotations__
83+
# attribute
8084
for i in reversed(removed):
81-
del dec.decorators[i]
85+
del decorators_to_store[i]
8286
# if the only decorators are register calls, we shouldn't treat this
8387
# as a decorated function because there aren't any decorators to apply
84-
if not dec.decorators:
88+
if not decorators_to_store:
8589
return
8690

87-
self.funcs_to_decorators[dec.func] = dec.decorators
91+
self.funcs_to_decorators[dec.func] = decorators_to_store
8892
super().visit_decorator(dec)
8993

9094
def visit_func_def(self, fdef: FuncItem) -> None:

0 commit comments

Comments
 (0)