Is StopIteration a singleton?

Steven D'Aprano steve at pearwood.info
Thu Nov 20 06:09:58 CET 2014


On Thu, 20 Nov 2014 12:52:25 +1100, Chris Angelico wrote:

> While poking about the cpython source tree with reference to PEP 479, I
> came across this:
> 
> https://docs.python.org/3.5/library/marshal.html
> 
> """singletons None, Ellipsis and StopIteration can also be marshalled
> and unmarshalled."""
> 
> StopIteration is a type. I suppose it's still kinda true that there's
> only one StopIteration class (otherwise exception handling would get
> very messy), but it seems unusual that this one particular exception
> class should be special-cased. (And yes, the code does correspond -
> marshal.c:293 handles StopIteration with its own byte code.)

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.

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


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



> 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



-- 
Steven



More information about the Python-list mailing list