PEP 255: Simple Generators, Revised Posting

Tim Peters tim.one at home.com
Sat Jun 23 14:28:19 EDT 2001


[Bernhard Herzog]
> With the current implementation that doesn't seem to be entirely true
> (CVS from somtime 2001-06-23 afternoon UTC):
>
> >>> def empty():
> ...     if 0: yield 0
> ...
> >>> for i in empty():
> ...     print i
> ...
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> TypeError: iter() of non-sequence
> >>> import dis
> >>> dis.dis(empty)
>           0 SET_LINENO               1
>
>           3 SET_LINENO               2
>           6 LOAD_CONST               0 (None)
>           9 RETURN_VALUE
> >>> empty.func_code.co_flags
> 3
>
> It seems that the mere lexical presence of the yield statement doesn't
> make a function a generator. The compiler apparently optimized the if
> statement away before testing whether it's a generator.

Yes, it does.  So don't do that.  This is a general glitchlet, i.e. not specific
to generators; e.g.

>>> k = 12
>>> def f():
...     if 0:
...         k = 3
...     print k
...
>>> f()
12
>>>

That didn't yield "the expected" UnboundLocalError for the same reason:  the
affected blocks are actually removed by the *parser*, and "the compiler" proper
never knows they were there -- the "if 0" blocks aren't even in the parse tree.
That makes it difficult to repair, and since nobody writes "if 0" in real life,
that in turn makes the cost/benefit ratio very high.  If you disagree, submit a
patch <wink>.

it's-way-over-my-threshold-ly y'rs  - tim





More information about the Python-list mailing list