diff --git a/mypyc/codegen/emit.py b/mypyc/codegen/emit.py index a882dc3800049..b20fde7faefa4 100644 --- a/mypyc/codegen/emit.py +++ b/mypyc/codegen/emit.py @@ -1442,7 +1442,7 @@ def emit_cpyfunction_instance( ) -> str: module = self.static_name(fn.decl.module_name, None, prefix=MODULE_PREFIX) cname = f"{PREFIX}{fn.cname(self.names)}" - wrapper_name = f"{cname}_wrapper" + wrapper_name = f"wrapper_{cname}" cfunc = f"(PyCFunction){cname}" func_flags = ["METH_FASTCALL", "METH_KEYWORDS"] if fn.class_name and fn.decl.kind == FUNC_STATICMETHOD: diff --git a/mypyc/codegen/emitclass.py b/mypyc/codegen/emitclass.py index 1a73d5426b851..2d8a0f30b064e 100644 --- a/mypyc/codegen/emitclass.py +++ b/mypyc/codegen/emitclass.py @@ -1506,7 +1506,7 @@ def success() -> None: name = short_id_from_name(fn.name, fn.decl.shortname, fn.line) wrapper_name = emit_instance(fn, name) - name_obj = f"{wrapper_name}_name" + name_obj = f"name_{wrapper_name}" emitter.emit_line(f'PyObject *{name_obj} = PyUnicode_FromString("{fn.name}");') emitter.emit_line(f"if (unlikely(!{name_obj}))") emitter.emit_line(error_stmt) diff --git a/mypyc/codegen/emitmodule.py b/mypyc/codegen/emitmodule.py index b8039dcca823c..34adecbe93e55 100644 --- a/mypyc/codegen/emitmodule.py +++ b/mypyc/codegen/emitmodule.py @@ -1249,7 +1249,7 @@ def emit_coroutine_wrappers(self, emitter: Emitter, module: ModuleIR, globals: s error_stmt = " goto fail;" name = short_id_from_name(fn.name, fn.decl.shortname, fn.line) wrapper_name = emitter.emit_cpyfunction_instance(fn, name, filepath, error_stmt) - name_obj = f"{wrapper_name}_name" + name_obj = f"name_{wrapper_name}" emitter.emit_line(f'PyObject *{name_obj} = PyUnicode_FromString("{fn.name}");') emitter.emit_line(f"if (unlikely(!{name_obj}))") emitter.emit_line(error_stmt) diff --git a/mypyc/test-data/run-async.test b/mypyc/test-data/run-async.test index 5eebb7348cf35..fa38e923a8b16 100644 --- a/mypyc/test-data/run-async.test +++ b/mypyc/test-data/run-async.test @@ -2135,6 +2135,47 @@ from typing import Any, Generator def run(x: object) -> object: ... +[case testCPyFunctionVariableNameConflict] +class C: + async def operation(self) -> int: + return 42 + + async def operation_name(self) -> str: + return "name" + + async def name_operation(self) -> str: + return await self.operation_name() + + async def operation_wrapper(self) -> int: + return await self.operation() + + async def wrapper_operation(self) -> int: + return await self.operation() + +async def test_variable_name_conflict() -> None: + c = C() + assert await c.operation() == 42 + assert await c.operation_wrapper() == 42 + assert await c.wrapper_operation() == 42 + assert await c.operation_name() == "name" + assert await c.name_operation() == "name" + +[file driver.py] +import asyncio + +from native import C, test_variable_name_conflict + +async def test_variable_name_conflict_interpreted() -> None: + c = C() + assert await c.operation() == 42 + assert await c.operation_wrapper() == 42 + assert await c.wrapper_operation() == 42 + assert await c.operation_name() == "name" + assert await c.name_operation() == "name" + +asyncio.run(test_variable_name_conflict()) +asyncio.run(test_variable_name_conflict_interpreted()) + [case testNestedCoroutineCallsAnotherNestedFunction] import asyncio import functools