Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.1k
Compiling Generators
Jukka Lehtosalo edited this page Oct 25, 2022 · 3 revisions
Generator functions must maintain state between invocations. A generator function is compiled into two classes. One is an environment class that maintains the local variables of the function, and the label/location where execution will continue (__mypyc_next_label__ attribute). The second class implements the actual generator. The environment class is similar to what mypyc uses to support nested functions.
For example, consider this simple generator:
deff(x: int) ->Iterator[int]: print('a') yieldxprint('b')This is compiled to something roughly like this (in heavily simplified pseudo-python):
deff(x: int) ->Iterator[int]: _env=f_env() _env.x=x_env.__mypyc_next_label__=0_gen=f_gen() _gen.__mypyc_env__=_envreturn_genclassf_env: x: int__mypyc_next_label__: intclassf_gen: __mypyc_env__: f_envdef__next__(self) ->int: _env=self.__mypyc_env___label=_env.__mypyc_next_label__if_label==0: print('a') _ret=_env.x_env.__mypyc_next_label__=1return_retelif_label==1: print('b') _env.__mypyc_next_label__=-1raiseStopIteration() else: raiseStopIteration() # Already completedThe actual generated code is more complicated because of error handling, and close/throw/send methods.