Skip to content

Commit

Permalink
[mypyc] Remangle redefined names produced by async with (#16408)
Browse files Browse the repository at this point in the history
Fixes mypyc/mypyc#1001.

---------

Co-authored-by: Jelle Zijlstra <[email protected]>
  • Loading branch information
ichard26 and JelleZijlstra committed Feb 28, 2024
1 parent 5a8cd80 commit 162c74d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
7 changes: 4 additions & 3 deletions mypyc/irbuild/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1246,14 +1246,15 @@ def add_var_to_env_class(
) -> AssignmentTarget:
# First, define the variable name as an attribute of the environment class, and then
# construct a target for that attribute.
self.fn_info.env_class.attributes[var.name] = rtype
attr_target = AssignmentTargetAttr(base.curr_env_reg, var.name)
name = remangle_redefinition_name(var.name)
self.fn_info.env_class.attributes[name] = rtype
attr_target = AssignmentTargetAttr(base.curr_env_reg, name)

if reassign:
# Read the local definition of the variable, and set the corresponding attribute of
# the environment class' variable to be that value.
reg = self.read(self.lookup(var), self.fn_info.fitem.line)
self.add(SetAttr(base.curr_env_reg, var.name, reg, self.fn_info.fitem.line))
self.add(SetAttr(base.curr_env_reg, name, reg, self.fn_info.fitem.line))

# Override the local definition of the variable to instead point at the variable in
# the environment class.
Expand Down
28 changes: 28 additions & 0 deletions mypyc/test-data/run-async.test
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,31 @@ async def foo() -> AsyncIterable[int]:
yields, val = run_generator(async_iter(foo()))
assert yields == (0,1,2), yields
assert val == 'lol no', val

[case testAsyncWithVarReuse]
class ConMan:
async def __aenter__(self) -> int:
return 1
async def __aexit__(self, *exc: object):
pass

class ConManB:
async def __aenter__(self) -> int:
return 2
async def __aexit__(self, *exc: object):
pass

async def x() -> None:
value = 2
async with ConMan() as f:
value += f
assert value == 3, value
async with ConManB() as f:
value += f
assert value == 5, value

[typing fixtures/typing-full.pyi]
[file driver.py]
import asyncio
import native
asyncio.run(native.x())

0 comments on commit 162c74d

Please sign in to comment.