How can I tell whether a generator was just-started?

This only works in Python 3.2+:

>>> def gen(): yield 0; yield 1
... 
>>> a = gen()
>>> import inspect
>>> inspect.getgeneratorstate(a)
'GEN_CREATED'
>>> next(a)
0
>>> inspect.getgeneratorstate(a)
'GEN_SUSPENDED'
>>> next(a)
1
>>> inspect.getgeneratorstate(a)
'GEN_SUSPENDED'
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> inspect.getgeneratorstate(a)
'GEN_CLOSED'

So, the requested function is:

import inspect

def is_just_started(gen):
    return inspect.getgeneratorstate(gen) == inspect.GEN_CREATED:

Out of curiosity, I looked into CPython to figure out how it was determining this… Apparently it looks at generator.gi_frame.f_lasti which is the “index of last attempted instruction in bytecode”. If it’s -1 then it hasn’t started yet.

Here’s a py2 version:

def is_just_started(gen):
    return gen.gi_frame is not None and gen.gi_frame.f_lasti == -1

Leave a Comment