Skip to content

Commit 3fd3b1c

Browse files
committed
Fix
1 parent e22ec9c commit 3fd3b1c

File tree

3 files changed

+44
-42
lines changed

3 files changed

+44
-42
lines changed

mypyc/irbuild/main.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ def f(x: int) -> int:
3939
from mypyc.irbuild.prebuildvisitor import PreBuildVisitor
4040
from mypyc.irbuild.prepare import (
4141
build_type_map,
42-
gen_generator_types,
43-
create_generator_class_if_needed,
42+
create_generator_class_for_func,
4443
find_singledispatch_register_impls,
44+
gen_generator_types,
4545
)
4646
from mypyc.irbuild.visitor import IRBuilderVisitor
4747
from mypyc.irbuild.vtable import compute_vtable
@@ -89,9 +89,11 @@ def build_ir(
8989
if isinstance(fdef, FuncDef):
9090
# Make generator class name sufficiently unique.
9191
suffix = f"___{fdef.line}"
92-
create_generator_class_if_needed(
93-
module.fullname, None, fdef, mapper, name_suffix=suffix
94-
)
92+
# TODO: decorated?
93+
if fdef.is_coroutine or fdef.is_generator:
94+
create_generator_class_for_func(
95+
module.fullname, None, fdef, mapper, name_suffix=suffix
96+
)
9597

9698
# Construct and configure builder objects (cyclic runtime dependency).
9799
visitor = IRBuilderVisitor()

mypyc/irbuild/mapper.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,7 @@ def fdef_to_sig(self, fdef: FuncDef, strict_dunders_typing: bool) -> FuncSignatu
180180
for typ, kind in zip(fdef.type.arg_types, fdef.type.arg_kinds)
181181
]
182182
arg_pos_onlys = [name is None for name in fdef.type.arg_names]
183-
# TODO: We could probably support decorators sometimes (static and class method?)
184-
if (fdef.is_coroutine or fdef.is_generator) and not fdef.is_decorated:
185-
# Give a more precise type for generators, so that we can optimize
186-
# code that uses them. They return a generator object, which has a
187-
# specific class. Without this, the type would have to be 'object'.
188-
ret: RType = RInstance(self.fdef_to_generator[fdef])
189-
else:
190-
ret = self.type_to_rtype(fdef.type.ret_type)
183+
ret = self.type_to_rtype(fdef.type.ret_type)
191184
else:
192185
# Handle unannotated functions
193186
arg_types = [object_rprimitive for _ in fdef.arguments]

mypyc/irbuild/prepare.py

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ def prepare_func_def(
196196
mapper: Mapper,
197197
options: CompilerOptions,
198198
) -> FuncDecl:
199-
#create_generator_class_if_needed(module_name, class_name, fdef, mapper)
200-
#assert False
199+
# create_generator_class_if_needed(module_name, class_name, fdef, mapper)
200+
# assert False
201201

202202
kind = (
203203
FUNC_CLASSMETHOD
@@ -210,38 +210,37 @@ def prepare_func_def(
210210
return decl
211211

212212

213-
def create_generator_class_if_needed(
213+
def create_generator_class_for_func(
214214
module_name: str, class_name: str | None, fdef: FuncDef, mapper: Mapper, name_suffix: str = ""
215-
) -> None:
216-
"""If function is a generator/async function, declare a generator class.
215+
) -> ClassIR:
216+
"""For a generator/async function, declare a generator class.
217217
218218
Each generator and async function gets a dedicated class that implements the
219219
generator protocol with generated methods.
220220
"""
221-
if fdef.is_coroutine or fdef.is_generator:
222-
name = "_".join(x for x in [fdef.name, class_name] if x) + "_gen" + name_suffix
223-
cir = ClassIR(name, module_name, is_generated=True, is_final_class=True)
224-
cir.reuse_freed_instance = True
225-
mapper.fdef_to_generator[fdef] = cir
221+
assert fdef.is_coroutine or fdef.is_generator
222+
name = "_".join(x for x in [fdef.name, class_name] if x) + "_gen" + name_suffix
223+
cir = ClassIR(name, module_name, is_generated=True, is_final_class=True)
224+
cir.reuse_freed_instance = True
225+
mapper.fdef_to_generator[fdef] = cir
226226

227-
helper_sig = FuncSignature(
228-
(
229-
RuntimeArg(SELF_NAME, object_rprimitive),
230-
RuntimeArg("type", object_rprimitive),
231-
RuntimeArg("value", object_rprimitive),
232-
RuntimeArg("traceback", object_rprimitive),
233-
RuntimeArg("arg", object_rprimitive),
234-
# If non-NULL, used to store return value instead of raising StopIteration(retv)
235-
RuntimeArg("stop_iter_ptr", object_pointer_rprimitive),
236-
),
237-
object_rprimitive,
238-
)
227+
helper_sig = FuncSignature(
228+
(
229+
RuntimeArg(SELF_NAME, object_rprimitive),
230+
RuntimeArg("type", object_rprimitive),
231+
RuntimeArg("value", object_rprimitive),
232+
RuntimeArg("traceback", object_rprimitive),
233+
RuntimeArg("arg", object_rprimitive),
234+
# If non-NULL, used to store return value instead of raising StopIteration(retv)
235+
RuntimeArg("stop_iter_ptr", object_pointer_rprimitive),
236+
),
237+
object_rprimitive,
238+
)
239239

240-
# The implementation of most generator functionality is behind this magic method.
241-
helper_fn_decl = FuncDecl(
242-
GENERATOR_HELPER_NAME, name, module_name, helper_sig, internal=True
243-
)
244-
cir.method_decls[helper_fn_decl.name] = helper_fn_decl
240+
# The implementation of most generator functionality is behind this magic method.
241+
helper_fn_decl = FuncDecl(GENERATOR_HELPER_NAME, name, module_name, helper_sig, internal=True)
242+
cir.method_decls[helper_fn_decl.name] = helper_fn_decl
243+
return cir
245244

246245

247246
def prepare_method_def(
@@ -816,5 +815,13 @@ def registered_impl_from_possible_register_call(
816815

817816
def gen_generator_types(mapper: Mapper, modules: list[MypyFile]) -> None:
818817
for fdef, ir in mapper.func_to_decl.items():
819-
if isinstance(fdef, FuncDef):
820-
create_generator_class_if_needed(ir.module_name, ir.class_name, fdef, mapper)
818+
if isinstance(fdef, FuncDef) and (fdef.is_coroutine or fdef.is_generator):
819+
gen_ir = create_generator_class_for_func(ir.module_name, ir.class_name, fdef, mapper)
820+
# TODO: We could probably support decorators sometimes (static and class method?)
821+
if not fdef.is_decorated:
822+
# Give a more precise type for generators, so that we can optimize
823+
# code that uses them. They return a generator object, which has a
824+
# specific class. Without this, the type would have to be 'object'.
825+
ir.sig.ret_type = RInstance(gen_ir)
826+
if ir.bound_sig:
827+
ir.bound_sig.ret_type = RInstance(gen_ir)

0 commit comments

Comments
 (0)