Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add comments and docstrings
  • Loading branch information
JukkaL committed Jul 4, 2025
commit 2c184dcd6a53cbd82e03693fffae331697d4dfa4
4 changes: 4 additions & 0 deletions mypyc/irbuild/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(self, group_map: dict[str, str | None]) -> None:
self.type_to_ir: dict[TypeInfo, ClassIR] = {}
self.func_to_decl: dict[SymbolNode, FuncDecl] = {}
self.symbol_fullnames: set[str] = set()
# The corresponding generator class that implements a generator/async function
self.fdef_to_generator: dict[FuncDef, ClassIR] = {}

def type_to_rtype(self, typ: Type | None) -> RType:
Expand Down Expand Up @@ -174,6 +175,9 @@ def fdef_to_sig(self, fdef: FuncDef, strict_dunders_typing: bool) -> FuncSignatu
arg_pos_onlys = [name is None for name in fdef.type.arg_names]
# TODO: We could probably support decorators sometimes (static and class method?)
if (fdef.is_coroutine or fdef.is_generator) and not fdef.is_decorated:
# Give a more precise type for generators, so that we can optimize
# code that uses them. They return a generator object, which has a
# specific class. Without this, the type would have to be 'object'.
ret = RInstance(self.fdef_to_generator[fdef])
else:
ret = self.type_to_rtype(fdef.type.ret_type)
Expand Down
6 changes: 6 additions & 0 deletions mypyc/irbuild/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ def prepare_func_def(
def create_generator_class_if_needed(
module_name: str, class_name: str | None, fdef: FuncDef, mapper: Mapper, name_suffix: str = ""
) -> None:
"""If function is a generator/async function, declare a generator class.

Each generator and async function gets a dedicated class that implements the
generator protocol with generated methods.
"""
if fdef.is_coroutine or fdef.is_generator:
name = "_".join(x for x in [fdef.name, class_name] if x) + "_gen" + name_suffix
cir = ClassIR(name, module_name, is_generated=True, is_final_class=True)
Expand All @@ -213,6 +218,7 @@ def create_generator_class_if_needed(
object_rprimitive,
)

# The implementation of most generator functionality is behind this magic method.
helper_fn_decl = FuncDecl(
"__mypyc_generator_helper__",
name,
Expand Down