Is StopIteration a singleton?

Chris Angelico rosuav at gmail.com
Thu Nov 20 06:16:01 CET 2014


On Thu, Nov 20, 2014 at 4:09 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> StopIteration is not a singleton class.
>
> py> e1 = StopIteration()
> py> e2 = StopIteration()
> py> e1 is e2
> False
>
> It it were, you couldn't support "return value" from generators, since
> the return value gets turned into the argument for StopIteration.

Clearly so. Also, the special case is for StopIteration, not for its
type (just as there is for None, and not NoneType).

> Nor is it a singleton itself: StopIteration (the class) is an instance of
> type, and there are *many* instances of type:
>
>
> py> all(isinstance(T, type) for T in [int, float, str, bool,
> ...     Exception, StopIteration, dict, type])
> True

Indeed; however, there is a fixed pointer PyExc_StopIteration at the C
level, so in a sense, there can be only one StopIteration. Even if you
shadow the name with a subclass, C code will still raise and look for
the original.

> I cannot imagine what they mean by calling StopIteration a singleton.

Okay, so I'm not the only one finds this strange!

>> Why is StopIteration marshallable but no other exception is? Or, if they
>> are marshallable, why does this one get special handling?
>
> No idea. But you can marshal StopIteration itself, but not StopIteration
> instances:
>
> py> marshal.dumps(StopIteration)
> 'S'
> py> marshal.dumps(StopIteration())
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ValueError: unmarshallable object

Under what circumstances would you marshal an exception type? I don't
use the module at all, I only happened upon it (its docs, to be
precise) by grepping across files.

ChrisA



More information about the Python-list mailing list