[Python-ideas] raising an exception type doesn't instantiate it until it gets caught

Michael Foord fuzzyman at gmail.com
Tue Nov 8 00:20:38 CET 2011


On 7 November 2011 23:06, Michael Foord <fuzzyman at gmail.com> wrote:

>
>
> On 7 November 2011 23:05, Michael Foord <fuzzyman at gmail.com> wrote:
>
>>
>>
>> On 7 November 2011 21:43, Gregory P. Smith <greg at krypto.org> wrote:
>>
>>>
>>>
>>> On Mon, Nov 7, 2011 at 12:05 PM, Cameron Simpson <cs at zip.com.au> wrote:
>>>
>>>> I wrote, naively:
>>>> | > I presume StopIteration would get instantiated to a singleton, like
>>>> | > NoneType to None? Just asking.
>>>>
>>>> On 07Nov2011 22:01, Nick Coghlan <ncoghlan at gmail.com> wrote:
>>>> | Even without the traceback issue Antoine mentioned, it's already the
>>>> | case that StopIteration isn't a singleton in 2.x. Various pieces of
>>>> | code (e.g. contextlib.contextmanager) rely on being able to tell
>>>> | whether they're getting a specific StopIteration instance back or a
>>>> | new one.
>>>>
>>>> Interesting.
>>>>
>>>> Off topic digression:
>>>>
>>>> I've been slightly uncomfortable about exceptions as control flow for a
>>>> while, basicly when writing code like this:
>>>>
>>>>  try:
>>>>    x = G.next()
>>>>  except StopIteration:
>>>>    # G is empty!
>>>>
>>>> in that I don't entirely know that the StopIteration came from G of from
>>>> some buggy code deeper inside G that let a StopIteration out, eg by
>>>> mangling a try/except like the above. In most circumstances with other
>>>> exceptions, while you might _expect_ the exception to come from the
>>>> source you expect you don't care so much because it will indicate
>>>> failure of the operation anyway. Report or die, you don't proceed as if
>>>> the op was good. But with StopIteration one is reading "G is empty"
>>>> directly into the situation and acting as though it is normal (exit the
>>>> event loop or whatever it may imply).
>>>>
>>>
>>> Agreed.  Use of exceptions for this in the language feels like it was a
>>> convenient way to do it but as the conditions aren't really *exceptional
>>> * at all it'd be nice if there were a lighter weight mechanism that
>>> could skip the unneeded parts of the exception raising and handling
>>> mechanism for the implementation.  We don't need the traceback to be stored
>>> in these situations.
>>>
>>> This existing logic to instantiate and associate the traceback with it
>>> only if caught is one way to implement doing exactly that. Any other ideas?
>>>
>>> Hackish things like a class attribute on classes being raised as an
>>> exception, or a LightweightException class being part of its class
>>> heirarchy used to signify if that exception should take the full path or
>>> the fast path come to mind but could be considered equally surprising.
>>>
>>> I'm not sure any of this is worth it but it would simplify the eval
>>> loop.  We're speaking implementation details of CPython here, not an actual
>>> change to the language itself. (*)
>>>
>>> -gps
>>>
>>> (*) Please beat anybody who writes code that depends on this somewhat
>>> odd exception instantiation timing behavior side effect over the head with
>>> a frozen herring.
>>>
>>
>>
>> Having the interpreter instantiate the exception for you allows you to do
>> wonderful things like this:
>>
>> >>> class Foo(Exception):
>> ...  def __new__(cls, *args):
>> ...   return object()
>> ...
>> >>> try:
>> ...  raise Foo
>> ... except Exception as e:
>> ...  print (e)
>> ...
>> <object object at 0x100634280>
>>
>> (I know this has nothing to do with the topic being debated but for some
>> reason this code tickles me. Plus it used to segfault Python 3...)
>>
>
>
> Ooh... this one segfaults Python 3.2 - I wonder if that's been fixed yet.
>
> >>> class Foo(Exception):
> ...  def __new__(cls, *args):
> ...   return 'string exception'
> ...
> >>> try:
> ...  raise Foo
> ... except Exception as e:
> ...  print (e)
> ...
> Segmentation fault: 11
>


Yeah, fixed on 3.2 branch and trunk. Sorry for all the noise. I finally
managed to get Python head to compile on OS X Lion, yay!

Michael


>
> All the best,
>
> Michael Foord
>
>
>>
>> All the best,
>>
>>
>> Michael
>>
>>
>>
>>>
>>>
>>>
>>>> On 07Nov2011 11:35, Antoine Pitrou <solipsis at pitrou.net> wrote:
>>>> | It is impossible to use singletons for exception instances now that
>>>> the
>>>> | traceback is stored on them.
>>>>
>>>> Ah. I had somehow thought the exception itself and the traceback were
>>>> distinct items, presented in a tuple.
>>>>
>>>> On 07Nov2011 21:15, Steven D'Aprano <steve at pearwood.info> wrote:
>>>> | Are you asking about what it should be, or what it is?
>>>>
>>>> The former.
>>>>
>>>> | Either way:
>>>> | >>> a = StopIteration('spam')
>>>> | >>> b = StopIteration('ham')
>>>> | >>> a is b
>>>> | False
>>>>
>>>> Since my question was about the proposed new behaviour when just a type
>>>> was raised, the above test wouldn't educate me. Though it does address
>>>> the
>>>> behaviour of the type instantation in general.
>>>>
>>>> Cheers,
>>>> --
>>>> Cameron Simpson <cs at zip.com.au> DoD#743
>>>> http://www.cskk.ezoshosting.com/cs/
>>>>
>>>> Carpe Datum     - John Sloan <jsloan at ncar.ucar.edu>
>>>> _______________________________________________
>>>> Python-ideas mailing list
>>>> Python-ideas at python.org
>>>> http://mail.python.org/mailman/listinfo/python-ideas
>>>>
>>>
>>>
>>> _______________________________________________
>>> Python-ideas mailing list
>>> Python-ideas at python.org
>>> http://mail.python.org/mailman/listinfo/python-ideas
>>>
>>>
>>
>>
>> --
>>
>> http://www.voidspace.org.uk/
>>
>> May you do good and not evil
>>
>> May you find forgiveness for yourself and forgive others
>>
>> May you share freely, never taking more than you give.
>> -- the sqlite blessing http://www.sqlite.org/different.html
>>
>>
>>
>
>
> --
>
> http://www.voidspace.org.uk/
>
> May you do good and not evil
> May you find forgiveness for yourself and forgive others
>
> May you share freely, never taking more than you give.
> -- the sqlite blessing http://www.sqlite.org/different.html
>
>
>


-- 

http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20111107/bf70ae76/attachment.html>


More information about the Python-ideas mailing list