TypeError + generator + str.join(): Bug or user error?

Tim Peters tim.peters at gmail.com
Mon Apr 10 23:31:27 EDT 2006


[Paul Du Bois]
> Using win32 python 2.4.1, I have a minimal test program:
>
> def generate():
>     raise TypeError('blah')
>     yield ""
>
> print "\n".join((generate()))
>
> Executing the program gives:
>
> Traceback (most recent call last):
>   File "<stdin>", line 5, in ?
> TypeError: sequence expected, generator found
>
> replacing TypeError with Exception gives what I would have expected: a
> traceback starting from the raise statement. I'm not relying on one
> behavior or the other, but I had a TypeError in a generator, and the
> funny exception slowed me down finding it.

I don't really think of it as "a bug" or a "user error".  Instead it's
a consquence of intractable complexity <0.5 wink>.  What can you pass
to join()?  "An iterable object" is the answer.  So what's "an
iterable object"?  Well, many things, but you can't always tell for
sure without _trying_ to iterate over it.  If the internal _attempt_
to iterate raises TypeError, the 2.4 join() interprets that as meaning
"ah, so this object doesn't support iteration after all -- let's raise
a TypeError of our own, explaining why we failed".

That's usually a good thing to do, but sometimes (as in your case) it
turns out it wasn't.  The internals got fiddled in 2.5 so that your
test case produces:

Traceback (most recent call last):
  File "pd.py", line 5, in <module>
    print "\n".join((generate()))
  File "pd.py", line 2, in generate
    raise TypeError('blah')
TypeError: blah

instead.  Since only God knows whether that makes some other test case
worse (probably not, but ...), and it's a change in visible behavior
regardless, that won't be backported to the 2.4 line.



More information about the Python-list mailing list