Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #81047 > unrolled thread

Is StopIteration a singleton?

Started byChris Angelico <rosuav@gmail.com>
First post2014-11-20 12:52 +1100
Last post2014-11-20 23:54 -0500
Articles 6 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Is StopIteration a singleton? Chris Angelico <rosuav@gmail.com> - 2014-11-20 12:52 +1100
    Re: Is StopIteration a singleton? Steven D'Aprano <steve@pearwood.info> - 2014-11-20 05:09 +0000
      Re: Is StopIteration a singleton? Chris Angelico <rosuav@gmail.com> - 2014-11-20 16:16 +1100
      Re: Is StopIteration a singleton? Terry Reedy <tjreedy@udel.edu> - 2014-11-20 22:40 -0500
      Re: Is StopIteration a singleton? Chris Angelico <rosuav@gmail.com> - 2014-11-21 15:23 +1100
      Re: Is StopIteration a singleton? Terry Reedy <tjreedy@udel.edu> - 2014-11-20 23:54 -0500

#81047 — Is StopIteration a singleton?

FromChris Angelico <rosuav@gmail.com>
Date2014-11-20 12:52 +1100
SubjectIs StopIteration a singleton?
Message-ID<mailman.16002.1416448354.18130.python-list@python.org>
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.)

Why is StopIteration marshallable but no other exception is? Or, if
they are marshallable, why does this one get special handling?

ChrisA

[toc] | [next] | [standalone]


#81054

FromSteven D'Aprano <steve@pearwood.info>
Date2014-11-20 05:09 +0000
Message-ID<546d77a5$0$12899$c3e8da3$5496439d@news.astraweb.com>
In reply to#81047
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

[toc] | [prev] | [next] | [standalone]


#81055

FromChris Angelico <rosuav@gmail.com>
Date2014-11-20 16:16 +1100
Message-ID<mailman.16006.1416460570.18130.python-list@python.org>
In reply to#81054
On Thu, Nov 20, 2014 at 4:09 PM, Steven D'Aprano <steve@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

[toc] | [prev] | [next] | [standalone]


#81164

FromTerry Reedy <tjreedy@udel.edu>
Date2014-11-20 22:40 -0500
Message-ID<mailman.16080.1416541252.18130.python-list@python.org>
In reply to#81054
On 11/20/2014 12:09 AM, Steven D'Aprano wrote:

> 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

Ditto for other exception classes I tried.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#81166

FromChris Angelico <rosuav@gmail.com>
Date2014-11-21 15:23 +1100
Message-ID<mailman.16081.1416543834.18130.python-list@python.org>
In reply to#81054
On Fri, Nov 21, 2014 at 2:40 PM, Terry Reedy <tjreedy@udel.edu> wrote:
> On 11/20/2014 12:09 AM, Steven D'Aprano wrote:
>
>> 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
>
>
> Ditto for other exception classes I tried.

I can't marshal any other exception instances, but I also can't
marshal any other exception classes. StopIteration is special-cased,
and I have no idea why.

ChrisA

[toc] | [prev] | [next] | [standalone]


#81169

FromTerry Reedy <tjreedy@udel.edu>
Date2014-11-20 23:54 -0500
Message-ID<mailman.16083.1416545723.18130.python-list@python.org>
In reply to#81054
On 11/20/2014 11:23 PM, Chris Angelico wrote:
> On Fri, Nov 21, 2014 at 2:40 PM, Terry Reedy <tjreedy@udel.edu> wrote:
>> On 11/20/2014 12:09 AM, Steven D'Aprano wrote:
>>
>>> 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
>>
>>
>> Ditto for other exception classes I tried.
>
> I can't marshal any other exception instances, but I also can't
> marshal any other exception classes. StopIteration is special-cased,
> and I have no idea why.

Sorry I was unclear.  I meant ditto ValueError for all other classes.


-- 
Terry Jan Reedy

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web