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