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


Groups > comp.lang.python > #88814

Re: try..except with empty exceptions

Date 2015-04-11 06:14 -0400
From Dave Angel <davea@davea.name>
Subject Re: try..except with empty exceptions
References <64a75c32-e0ab-4ce0-9373-358c2669fe6e@googlegroups.com> <785010c0-6bcc-46d7-b7e0-0ed062fabbc7@googlegroups.com> <55287c0d$0$13000$c3e8da3$5496439d@news.astraweb.com> <mailman.211.1428718999.12925.python-list@python.org> <5528c906$0$12994$c3e8da3$5496439d@news.astraweb.com>
Newsgroups comp.lang.python
Message-ID <mailman.218.1428747278.12925.python-list@python.org> (permalink)

Show all headers | View raw


On 04/11/2015 03:11 AM, Steven D'Aprano wrote:
> On Sat, 11 Apr 2015 12:23 pm, Dave Angel wrote:
>
>> On 04/10/2015 09:42 PM, Steven D'Aprano wrote:
>>> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82@gmail.com wrote:
>>>
>>>> It isn't document because it is expected.  Why would the exception get
>>>> caught if you're not writing code to catch it?  If you write a function
>>>> and pass it a tuple of exceptions to catch, I'm not sure why you would
>>>> expect it to catch an exception not in the tuple.  Just because the
>>>> tuple
>>>> is empty doesn't mean that it should catch *everything* instead.  That
>>>> would be counter-intuitive.
>>>
>>> Really? I have to say, I expected it.
>>>
>>>
>>
>> I'm astounded at your expectation.  That's like saying a for loop on an
>> empty list ought to loop on all possible objects in the universe.
>
> Not really.
>
> If we wrote:
>
>      for x in:
>          # Missing sequence leads to an infinite loop
>
> *then* your analogy would be excellent, but it isn't. With for loops, we
> iterate over each item in the sequence, hence an empty sequence means we
> don't iterate at all.
>
> But with try...except, an empty exception list means to catch *everything*,
> not nothing:

No an empty exception list means to catch nothing.  A *missing* 
exception list means catch everything, but that's a different syntax
>
> try: ...
> except a,b,c: # catches a, b, c
>
> try: ...
> except a,b: # catches a, b
>
> try: ...
> except a: # catches a

try: ...
except (a,)   #catches a

try: ...
except ()  #catches nothing, as expected

>
> try: ...
> except: # catches EVERYTHING, not nothing
>

Different syntax.  No reason for it to pretend that it's being given an 
empty tuple or list.

>
> Putting (a, b, c) into a tuple shouldn't make a difference, and it doesn't,
> unless the tuple is empty. That surprised me.
>
> t = a, b, c
> try:
> except t:  # same as except a,b,c
>
> t = a, b
> try:
> except t:  # same as except a,b
>
> t = a,
> try:
> except t:  # same as except a
>
> t = ()
> try:
> except t:  # NOT THE SAME as bare except.

Of course not.  It's empty, so it catches nothing. Just like 'for'

>
>
> I can see the logic behind the current behaviour. If you implement except
> clauses like this pseudo-code:
>
>
> for exc in exceptions:
>      if raised_exception matches exc: catch it
>
>
> then an empty tuple will naturally lead to nothing being caught. That
> doesn't mean it isn't surprising from the perspective that an empty
> exception list (i.e. a bare except) should be analogous to an empty tuple.

Why should it??  It's a different syntax, with different rules.  Perhaps 
it should have been consistent, but then it's this statement that's 
surprising, not the behavior with an empty tuple.

>
>
>> The tuple lists those exceptions you're interested in, and they are
>> tried, presumably in order, from that collection.  If none of those
>> match, then the logic will advance to the next except clause.  If the
>> tuple is empty, then clearly none will match.
>
> Yes, that makes sense, and I agree that it is reasonable behaviour from one
> perspective. But its also reasonable to treat "except ():" as analogous to
> a bare except.
>
> [...]
>>> try:
>>>       spam()
>>> except:
>>>       # Implicitly an empty tuple.
>>
>> No, an omitted item is not the same as an empty tuple.
>
> You are correct about Python as it actually is, but it could have been
> designed so that except (): was equivalent to a bare except.

Only by changing the bare except behavior.

>
>
>> If it were, then
>> we wouldn't have the problem of bare excepts, which are so tempting to
>> novices.  There's plenty of precedent in many languages for a missing
>> item being distinct from anything one could actually supply.
>
> Let us put aside the fact that some people misuse bare excepts, and allow
> that there are some uses for it. Now, in Python 2.6 and later, you can
> catch everything by catching BaseException. But in older versions, you
> could raise strings as well, and the only way to catch everything is with a
> bare except.
>
> If you want to write a function that takes a list of things to catch,
> defaulting to "everything", in Python 2.6+ we can write:
>
> def spam(things_to_catch=BaseException):
>      try:
>          do_stuff()
>      except things_to_catch:
>          handle_exception()
>
>
> but in older versions you have to write this:
>
> def spam(things_to_catch=None):
>      if things_to_catch is None:
>          try:
>              do_stuff()
>          except:
>              handle_exception()
>      else:
>          try:
>              do_stuff()
>          except things_to_catch:
>              handle_exception()
>
>
> This violates Don't Repeat Yourself. Any time you have "a missing item being
> distinct from anything one could actually supply", you have a poor design.

Yep, and it happens all the time.  For example, mylist[a,b,-1]    What 
value can I use for b to mean the whole list?

There are others more grotesque, but I can't think of any at this moment.

>
> Anyway, in modern Python (2.6 onwards), now that string exceptions are gone,
> you can supply something to catch everything. Or nothing, for that matter:
>
> BaseException  # catch everything
> Exception  # catch errors
> (A, B, C)  # Just A, B or C or their subclasses
> A  # Just A (or its subclasses)
> ()  # Catch nothing.
>
> so I suppose that having an empty tuple mean "catch nothing" is better than
> having it catch everything.
>

Just like with all(()) and any(()), there's a logical way and an 
illogical way.  An empty list means no items, not all possible items.



-- 
DaveA

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

try..except with empty exceptions Pavel S <pavel@schon.cz> - 2015-04-10 01:48 -0700
  Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-10 18:58 +1000
  Re: try..except with empty exceptions sohcahtoa82@gmail.com - 2015-04-10 12:31 -0700
    Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 11:42 +1000
      Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-10 22:23 -0400
        Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 19:38 -0700
          Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-10 23:46 -0400
            Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 21:17 -0700
              Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 21:39 -0700
          Re: try..except with empty exceptions Cameron Simpson <cs@zip.com.au> - 2015-04-11 19:27 +1000
            Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 21:00 +1000
              Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-11 21:21 +1000
              Re: try..except with empty exceptions Ian Kelly <ian.g.kelly@gmail.com> - 2015-04-11 12:49 -0600
              Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-12 06:04 +1000
              Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-12 06:05 +1000
        Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 17:11 +1000
          Re: try..except with empty exceptions Serhiy Storchaka <storchaka@gmail.com> - 2015-04-11 11:22 +0300
            Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 20:47 +1000
          Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-11 06:14 -0400
          Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-11 06:24 -0400
          Re: try..except with empty exceptions Ian Foote <ian@feete.org> - 2015-04-11 15:20 +0100
      Re: try..except with empty exceptions Terry Reedy <tjreedy@udel.edu> - 2015-04-11 04:58 -0400
  Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-10 16:27 -0400
  Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 18:56 -0700

csiph-web