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


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

How come StopIteration.__base__ is not BaseException?

Started byMarco Buttu <marco.buttu@gmail.com>
First post2013-08-26 21:37 +0200
Last post2013-08-27 13:00 -0700
Articles 10 — 5 participants

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


Contents

  How come StopIteration.__base__ is not BaseException? Marco Buttu <marco.buttu@gmail.com> - 2013-08-26 21:37 +0200
    Re: How come StopIteration.__base__ is not BaseException? random832@fastmail.us - 2013-08-26 16:10 -0400
      Re: How come StopIteration.__base__ is not BaseException? Marco Buttu <marco.buttu@gmail.com> - 2013-08-27 08:17 +0200
        Re: How come StopIteration.__base__ is not BaseException? Marco Buttu <marco.buttu@gmail.com> - 2013-08-27 08:18 +0200
        Re: How come StopIteration.__base__ is not BaseException? Steven D'Aprano <steve@pearwood.info> - 2013-08-27 09:22 +0000
          Re: How come StopIteration.__base__ is not BaseException? Marco Buttu <marco.buttu@gmail.com> - 2013-08-27 12:02 +0200
            Re: How come StopIteration.__base__ is not BaseException? Terry Reedy <tjreedy@udel.edu> - 2013-08-27 14:51 -0400
              Re: How come StopIteration.__base__ is not BaseException? Marco Buttu <marco.buttu@gmail.com> - 2013-08-27 21:52 +0200
                Re: How come StopIteration.__base__ is not BaseException? Terry Reedy <tjreedy@udel.edu> - 2013-08-27 16:37 -0400
    Re: How come StopIteration.__base__ is not BaseException? Ethan Furman <ethan@stoneleaf.us> - 2013-08-27 13:00 -0700

#53012 — How come StopIteration.__base__ is not BaseException?

FromMarco Buttu <marco.buttu@gmail.com>
Date2013-08-26 21:37 +0200
SubjectHow come StopIteration.__base__ is not BaseException?
Message-ID<kvgapp$lh3$1@speranza.aioe.org>
Since StopIteration is not an error, how come does it inherit directly 
from Exception and not from BaseException?

Thanks in advance, Marco
-- 
Marco

[toc] | [next] | [standalone]


#53015

Fromrandom832@fastmail.us
Date2013-08-26 16:10 -0400
Message-ID<mailman.246.1377547832.19984.python-list@python.org>
In reply to#53012
On Mon, Aug 26, 2013, at 15:37, Marco Buttu wrote:
> Since StopIteration is not an error, how come does it inherit directly 
> from Exception and not from BaseException?

The reason KeyboardInterrupt and SystemExit inherit from BaseException
is because you often want them to escape (allowing the program to quit)
from code that would otherwise catch them (by catching Exception). On
the contrary, StopIteration is almost always used in a context that
catches it specifically.

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


#53031

FromMarco Buttu <marco.buttu@gmail.com>
Date2013-08-27 08:17 +0200
Message-ID<521C446B.9040605@gmail.com>
In reply to#53015
On 08/26/2013 10:10 PM, random832@fastmail.us wrote:

> The reason KeyboardInterrupt and SystemExit inherit from BaseException
> is because you often want them to escape (allowing the program to quit)
> from code that would otherwise catch them (by catching Exception). On
> the contrary, StopIteration is almost always used in a context that
> catches it specifically.

But if I want to catch it specifically (except BaseIteration), why
doesn't it hinerit directly from BaseException? It's not an error and 
it's not a warning. I would like to see a piece of code in which it is
useful to catch it generically with a except Exception clause instead of 
an except StopIteration...
Regards
-- 
Marco

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


#53032

FromMarco Buttu <marco.buttu@gmail.com>
Date2013-08-27 08:18 +0200
Message-ID<kvhgbo$9ai$2@speranza.aioe.org>
In reply to#53031
On 08/27/2013 08:17 AM, Marco Buttu wrote:
> But if I want to catch it specifically (except BaseIteration),


Sorry, except StopIteration...
-- 
Marco Buttu

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


#53041

FromSteven D'Aprano <steve@pearwood.info>
Date2013-08-27 09:22 +0000
Message-ID<521c6fb9$0$11100$c3e8da3@news.astraweb.com>
In reply to#53031
On Tue, 27 Aug 2013 08:17:15 +0200, Marco Buttu wrote:

> On 08/26/2013 10:10 PM, random832@fastmail.us wrote:
> 
>> The reason KeyboardInterrupt and SystemExit inherit from BaseException
>> is because you often want them to escape (allowing the program to quit)
>> from code that would otherwise catch them (by catching Exception). On
>> the contrary, StopIteration is almost always used in a context that
>> catches it specifically.
> 
> But if I want to catch it specifically (except BaseIteration), why

You mean StopIteration.

> doesn't it hinerit directly from BaseException? It's not an error and
> it's not a warning. I would like to see a piece of code in which it is
> useful to catch it generically with a except Exception clause instead of
> an except StopIteration...

You are focused on the wrong thing. It doesn't matter that we normally 
catch StopIteration specifically. We normally catch *all* exceptions 
specifically. 

try: 
    ...
except ValueError:
    ...

This doesn't mean that ValueError should inherit from BaseException. So 
the fact that we catch StopIteration specifically too doesn't mean it 
needs to inherit from BaseException.

What matters is that when you catch "nearly everything", StopIteration is 
included in the "nearly everything", but SysExit and KeyboardInterrupt 
should not be. Consider:


try:
    main()
except Exception as e:
    print('an unexpected error occurred')
    log_unhandled_exception(e)
    emergency_shutdown()
    sys.exit(1)
except (KeyboardInterrupt, SysExit):
    # User wants to exit.
    clean_exit()
    sys.exit(0)



Which except clause would you expect an unhandled StopIteration to fall 
under? The unexpected error clause, or the "user wants to exit cleanly" 
clause?



-- 
Steven

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


#53049

FromMarco Buttu <marco.buttu@gmail.com>
Date2013-08-27 12:02 +0200
Message-ID<521C7935.8080205@gmail.com>
In reply to#53041
On 08/27/2013 11:22 AM, Steven D'Aprano wrote:
>
> What matters is that when you catch "nearly everything", StopIteration is
> included in the "nearly everything", but SysExit and KeyboardInterrupt
> should not be. Consider:
>
>
> try:
>      main()
> except Exception as e:
>      print('an unexpected error occurred')
>      log_unhandled_exception(e)
>      emergency_shutdown()
>      sys.exit(1)
> except (KeyboardInterrupt, SysExit):
>      # User wants to exit.
>      clean_exit()
>      sys.exit(0)
>
>
>
> Which except clause would you expect an unhandled StopIteration to fall
> under? The unexpected error clause, or the "user wants to exit cleanly"
> clause?

Thanks Steven, that was clear for me. I was thinking about a design 
concept: how come doesn't it inherit directly from BaseException like 
GeneratorExit does? But I think I got the answer: because we can iterate 
manually and so it can propagate, and so we want an except Exception 
clause catches it.

Thanks, Marco

-- 
Marco

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


#53084

FromTerry Reedy <tjreedy@udel.edu>
Date2013-08-27 14:51 -0400
Message-ID<mailman.278.1377629540.19984.python-list@python.org>
In reply to#53049
On 8/27/2013 6:02 AM, Marco Buttu wrote:
> On 08/27/2013 11:22 AM, Steven D'Aprano wrote:
>>
>> What matters is that when you catch "nearly everything", StopIteration is
>> included in the "nearly everything", but SysExit and KeyboardInterrupt
>> should not be. Consider:
>>
>>
>> try:
>>      main()
>> except Exception as e:
>>      print('an unexpected error occurred')
>>      log_unhandled_exception(e)
>>      emergency_shutdown()
>>      sys.exit(1)
>> except (KeyboardInterrupt, SysExit):
>>      # User wants to exit.
>>      clean_exit()
>>      sys.exit(0)
>>
>>
>>
>> Which except clause would you expect an unhandled StopIteration to fall
>> under? The unexpected error clause, or the "user wants to exit cleanly"
>> clause?
>
> Thanks Steven, that was clear for me. I was thinking about a design
> concept: how come doesn't it inherit directly from BaseException like
> GeneratorExit does? But I think I got the answer: because we can iterate
> manually and so it can propagate, and so we want an except Exception
> clause catches it.

Until relatively recently, in 2.5, Exception *was* the base exception 
class and for nearly everything, it still is. "All built-in, 
non-system-exiting exceptions are derived from this class. All 
user-defined exceptions should also be derived from this class." 
BaseException was added just so it would be possible to catch nearly 
everything but a few exceptions. The first two were KeyboardInterrupt 
and SystemExit (in 2.5). GeneratorExit was switched in 2.6, but I forget 
the details of why.

-- 
Terry Jan Reedy

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


#53087

FromMarco Buttu <marco.buttu@gmail.com>
Date2013-08-27 21:52 +0200
Message-ID<kvj01v$s20$1@speranza.aioe.org>
In reply to#53084
On 08/27/2013 08:51 PM, Terry Reedy wrote:

> BaseException was added just so it would be possible to catch nearly
> everything but a few exceptions. The first two were KeyboardInterrupt
> and SystemExit (in 2.5). GeneratorExit was switched in 2.6, but I forget
> the details of why.

Maybe in order to don't catch it inside a generator using a except 
Exception clause, because it is used to notify an active generator is 
closed:

 >>> def foogen():
...     for i in range(10):
...         try:
...             yield i
...         except:
...             print('Catched!')
...             # raise
...
 >>> g = foogen()
 >>> next(g)
0
 >>> g.close()
Catched!
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
RuntimeError: generator ignored GeneratorExit

Do you remember if this is the reason? Thanks,
-- 
Marco

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


#53092

FromTerry Reedy <tjreedy@udel.edu>
Date2013-08-27 16:37 -0400
Message-ID<mailman.283.1377635844.19984.python-list@python.org>
In reply to#53087
On 8/27/2013 3:52 PM, Marco Buttu wrote:
> On 08/27/2013 08:51 PM, Terry Reedy wrote:
>
>> BaseException was added just so it would be possible to catch nearly
>> everything but a few exceptions. The first two were KeyboardInterrupt
>> and SystemExit (in 2.5). GeneratorExit was switched in 2.6, but I forget
>> the details of why.
>
> Maybe in order to don't catch it inside a generator using a except
> Exception clause, because it is used to notify an active generator is
> closed:
>
>  >>> def foogen():
> ...     for i in range(10):
> ...         try:
> ...             yield i
> ...         except:
> ...             print('Catched!')
> ...             # raise
> ...
>  >>> g = foogen()
>  >>> next(g)
> 0
>  >>> g.close()
> Catched!
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> RuntimeError: generator ignored GeneratorExit
>
> Do you remember if this is the reason? Thanks,

I only remember that there was a 'problem' that necessitated a change in 
2.6 after the introduction in 2.5. The above seems reasonable.

-- 
Terry Jan Reedy

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


#53095

FromEthan Furman <ethan@stoneleaf.us>
Date2013-08-27 13:00 -0700
Message-ID<mailman.285.1377636565.19984.python-list@python.org>
In reply to#53012
On 08/26/2013 12:37 PM, Marco Buttu wrote:
>
> Since StopIteration is not an error, how come does it inherit directly from Exception and not from BaseException?

Not all exceptions are errors. (Although not dealing with one can be. ;)

--
~Ethan~

[toc] | [prev] | [standalone]


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


csiph-web