@@ -5,13 +5,15 @@ Generators and Coroutines
55Generators
66----------
77
8- The implementation of generators in CPython consists of instances of ` PyGenObject `
9- and bytecode instructions that operate on instances of this type.
10-
11- A generator object is invoked in a [ ` frame ` ] ( frames.md ) , like a function.
12- The difference is that a function returns to the calling frame only once,
13- while a generator "returns" to the caller every time it emits a new item
14- with a
8+ Generators in CPython are implemented with the struct ` PyGenObject ` .
9+ They consist of a [ ` frame ` ] ( frames.md ) and metadata about the generator's
10+ execution state.
11+
12+ A generator object resumes execution in its frame when its ` send() `
13+ method is called. This is analogous to a function executing in its own
14+ fram when it is called, but a function returns to the calling frame only once,
15+ while a generator "returns" execution to the caller's frame every time
16+ it emits a new item with a
1517[ ` yield ` expression] ( https://docs.python.org/dev/reference/expressions.html#yield-expressions ) .
1618This is implemented by the
1719[ ` YIELD_VALUE ` ] ( https://docs.python.org/dev/library/dis.html#opcode-YIELD_VALUE )
@@ -38,16 +40,17 @@ Generator Object Creation and Destruction
3840
3941The bytecode of a generator function begins with a
4042[ ` RETURN_GENERATOR ` ] ( https://docs.python.org/dev/library/dis.html#opcode-RETURN_GENERATOR )
41- instruction, which creates a generator object, along with its embedded frame.
43+ instruction, which creates a generator object, including its embedded frame.
4244The generator's frame is initialized as a copy of the frame in which
4345` RETURN_GENERATOR ` is executing, but its ` owner ` field is overwritten to indicate
4446that it is owned by a generator. Finally, ` RETURN_GENERATOR ` pushes the new generator
45- object to the stack and returns to the caller of the generator function. When the
46- generator is next resumed by [ ` gen_send_ex2() ` ] ( ../Objects/genobject.c ) ,
47- ` _PyEval_EvalFrame() ` is called to continue executing the generator function,
48- in the frame that is embedded in the generator object.
47+ object to the stack and returns to the caller of the generator function (at
48+ which time its frame is destroyed). When the generator is next resumed by
49+ [ ` gen_send_ex2() ` ] ( ../Objects/genobject.c ) , ` _PyEval_EvalFrame() ` is called
50+ to continue executing the generator function, in the frame that is embedded in
51+ the generator object.
4952
50- When a generator object is destructed in [ ` gen_dealloc ` ] ( ../Objects/genobject.c ) ,
53+ When a generator object is destroyed in [ ` gen_dealloc ` ] ( ../Objects/genobject.c ) ,
5154its embedded ` _PyInterpreterFrame ` field may need to be preserved, if it is exposed
5255to Python as part of a [ ` PyFrameObject ` ] ( frames.md#frame-objects ) . This is detected
5356in [ ` _PyFrame_ClearExceptCode ` ] ( ../Python/frame.c ) by the fact that the interpreter
@@ -63,7 +66,9 @@ The [`FOR_ITER`](https://docs.python.org/dev/library/dis.html#opcode-FOR_ITER)
6366instruction calls ` __next__ ` on the iterator which is on the top of the stack,
6467and pushes the result to the stack. It has [ ` specializations ` ] ( adaptive.md )
6568for a few common iterator types, including ` FOR_ITER_GEN ` , for iterating over
66- a generator.
69+ a generator. ` FOR_ITER_GEN ` bypasses the call to ` __next__ ` , and instead
70+ directly pushes the generator stack and resumes its execution from the
71+ instruction that follows the last yield.
6772
6873Chained Generators
6974------------------
0 commit comments