Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion mypyc/irbuild/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,12 @@ def add_local(self, symbol: SymbolNode, typ: RType, is_arg: bool = False) -> 'Re
is_arg: is this a function argument
"""
assert isinstance(symbol, SymbolNode)
reg = Register(typ, symbol.name, is_arg=is_arg, line=symbol.line)
reg = Register(
typ,
remangle_redefinition_name(symbol.name),
is_arg=is_arg,
line=symbol.line,
)
self.symtables[-1][symbol] = AssignmentTargetRegister(reg)
if is_arg:
self.builder.args.append(reg)
Expand Down Expand Up @@ -1203,3 +1208,14 @@ def get_default() -> Value:
GetAttr(builder.fn_info.callable_class.self_reg, name, arg.line))
assert isinstance(target, AssignmentTargetRegister)
builder.assign_if_null(target.register, get_default, arg.initializer.line)


def remangle_redefinition_name(name: str) -> str:
"""Remangle names produced by mypy when allow-redefinition is used and a name
is used with multiple types within a single block.

We only need to do this for locals, because the name is used as the name of the register;
for globals, the name itself is stored in a register for the purpose of doing dict
lookups.
"""
return name.replace("'", "__redef__")
24 changes: 24 additions & 0 deletions mypyc/test-data/irbuild-basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -3745,3 +3745,27 @@ L3:
goto L1
L4:
return 1
[case testLocalRedefinition]
# mypy: allow-redefinition
def f() -> None:
i = 0
i += 1
i = "foo"
i += i
i = 0.0
[out]
def f():
i, r0 :: int
r1, i__redef__, r2 :: str
r3, i__redef____redef__ :: float
L0:
i = 0
r0 = CPyTagged_Add(i, 2)
i = r0
r1 = 'foo'
i__redef__ = r1
r2 = CPyStr_Append(i__redef__, i__redef__)
i__redef__ = r2
r3 = 0.0
i__redef____redef__ = r3
return 1
11 changes: 11 additions & 0 deletions mypyc/test-data/run-misc.test
Original file line number Diff line number Diff line change
Expand Up @@ -1089,3 +1089,14 @@ class A:
class B(A):
def _(arg): pass
def _(arg): pass

[case testGlobalRedefinition_toplevel]
# mypy: allow-redefinition
i = 0
i += 1
i = "foo"
i += i
i = b"foo"

def test_redefinition() -> None:
assert i == b"foo"