For 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.
(
module_name: str, class_name: str | None, fdef: FuncDef, mapper: Mapper, name_suffix: str = ""
)
| 234 | |
| 235 | |
| 236 | def create_generator_class_for_func( |
| 237 | module_name: str, class_name: str | None, fdef: FuncDef, mapper: Mapper, name_suffix: str = "" |
| 238 | ) -> ClassIR: |
| 239 | """For a generator/async function, declare a generator class. |
| 240 | |
| 241 | Each generator and async function gets a dedicated class that implements the |
| 242 | generator protocol with generated methods. |
| 243 | """ |
| 244 | assert fdef.is_coroutine or fdef.is_generator |
| 245 | name = "_".join(x for x in [fdef.name, class_name] if x) + "_gen" + name_suffix |
| 246 | cir = ClassIR(name, module_name, is_generated=True, is_final_class=class_name is None) |
| 247 | cir.reuse_freed_instance = True |
| 248 | mapper.fdef_to_generator[fdef] = cir |
| 249 | |
| 250 | helper_sig = FuncSignature( |
| 251 | ( |
| 252 | RuntimeArg(SELF_NAME, object_rprimitive), |
| 253 | RuntimeArg("type", object_rprimitive), |
| 254 | RuntimeArg("value", object_rprimitive), |
| 255 | RuntimeArg("traceback", object_rprimitive), |
| 256 | RuntimeArg("arg", object_rprimitive), |
| 257 | # If non-NULL, used to store return value instead of raising StopIteration(retv) |
| 258 | RuntimeArg("stop_iter_ptr", object_pointer_rprimitive), |
| 259 | ), |
| 260 | object_rprimitive, |
| 261 | ) |
| 262 | |
| 263 | # The implementation of most generator functionality is behind this magic method. |
| 264 | helper_fn_decl = FuncDecl(GENERATOR_HELPER_NAME, name, module_name, helper_sig, internal=True) |
| 265 | cir.method_decls[helper_fn_decl.name] = helper_fn_decl |
| 266 | return cir |
| 267 | |
| 268 | |
| 269 | def prepare_method_def( |
no test coverage detected
searching dependent graphs…