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


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

Re: try..except with empty exceptions

Started byCameron Simpson <cs@zip.com.au>
First post2015-04-12 09:08 +1000
Last post2015-04-12 16:47 +1000
Articles 3 — 2 participants

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

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: try..except with empty exceptions Cameron Simpson <cs@zip.com.au> - 2015-04-12 09:08 +1000
    Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-12 14:18 +1000
      Re: try..except with empty exceptions Cameron Simpson <cs@zip.com.au> - 2015-04-12 16:47 +1000

#88846 — Re: try..except with empty exceptions

FromCameron Simpson <cs@zip.com.au>
Date2015-04-12 09:08 +1000
SubjectRe: try..except with empty exceptions
Message-ID<mailman.236.1428793684.12925.python-list@python.org>
On 12Apr2015 07:52, Chris Angelico <rosuav@gmail.com> wrote:
>On Sun, Apr 12, 2015 at 7:37 AM, Cameron Simpson <cs@zip.com.au> wrote:
>> On 11Apr2015 21:21, Chris Angelico <rosuav@gmail.com> wrote:
>>> But I agree, it would be very nice if Python 3 could have abolished
>>> the truly confusing part of this, where "except:" catches everything.
>>> Forcing people to spell it "except BaseException:" would fix all of
>>> this. How hard is it to deprecate and then remove that, same as string
>>> exceptions were removed?
>>
>> I guess I'll go over there to oppose it then.
>>
>> Why? It makes it harder to write portable python 2/3 code and does not add
>> any semantic advantage.
>>
>> Unless there's a common root exception class in Python 2, which I believe
>> there isn't, you can't catch all exceptions in python 2 without the
>> "except:" syntax.  Which means the _only_ way to have some code in both 2
>> and 3 that does it requires 2 codebases.
>>
>> As one who tries to have his code run in both 2 (usually recent 2, like
>> 2.6/2.7) and 3, this change would cause a signification breakage for me
>> without bringing any semantic benefits.
>
>Can you give an example of a place where in Py2 you absolutely have to
>catch everything, and don't have control over the code, *and* are
>trying to do a one-codebase routine with Py3 compatibility? If you're
>trying for 2/3 compatibility, you'll need to have all your exceptions
>derive from BaseException anyway.

I don't make many personal exception classes, tending to reuse stdlib ones. I'm 
sure I have a few.

But regarding codebase:

    [hg/css]fleet*> g except: **/*.py
    lib/python/cs/app/pilfer.py:664:              except:
    lib/python/cs/asynchron.py:145:    except:
    lib/python/cs/db.py:184:      except:
    lib/python/cs/excutils.py:34:  except:
    lib/python/cs/fileutils.py:69:  except:
    lib/python/cs/idset.py:46:      except:
    lib/python/cs/later.py:156:    except:
    lib/python/cs/mailutils.py:274:      except:
    lib/python/cs/nodedb/tokcab.py:57:    except:
    lib/python/cs/queues.py:441:          except:
    lib/python/cs/queues.py:458:              except:
    lib/python/cs/threads.py:131:      except:

Catching all exceptions isn't terribly common, _except_ in service routines 
that wrap "unknown" operations. Classic example from my Asynchron class:

    def call(self, func, *a, **kw):
      ''' Have the Asynchron call `func(*a,**kw)` and store its values as
          self.result.
          If `func` raises an exception, store it as self.exc_info.
      '''
      try:
        r = func(*a, **kw)
      except:
        self.exc_info = sys.exc_info
      else:
        self.result = r

All sorts of things like thread pools and other "worker" functions, and 
run-forever daemons like mail filers that can have arbitrary exceptions occur 
in (partly) third party code eg from config files; you need to catch any 
unknown exception and fail the specific action, but continue the main daemon 
operation.

And since I use this code in Python 2, and since not all exceptions are 
BaseException subclasses, I need the bare syntax.

Also, IMO, a bare "except:" syntax is _far_ more pleasing to the eye than 
"except magic_exception_name_that+gets_everything:". Also, I wish 
"BaseException" were just spelled "Exception", if it has to be used.

>At very worst, it could be turned into a compat-only syntax feature,
>like the u"spam" noise prefix on Unicode strings - serving absolutely
>no purpose in Py3 code, and ideally, able to be removed at some point
>post-2020.

I'm -0.1 on the idea myself. I consider "except:" succinct and evocative, and 
prefer it to "except BaseException:".

Cheers,
Cameron Simpson <cs@zip.com.au>

On a videophone, the whole world can see you fart.      - Charlie Stross

[toc] | [next] | [standalone]


#88854

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-04-12 14:18 +1000
Message-ID<5529f229$0$13010$c3e8da3$5496439d@news.astraweb.com>
In reply to#88846
On Sun, 12 Apr 2015 09:08 am, Cameron Simpson wrote:

> Also, IMO, a bare "except:" syntax is far more pleasing to the eye than
> "except magic_exception_name_that+gets_everything:".


And that is exactly what makes bare excepts an attractive nuisance!

I'm going to channel a newbie, cowboy or just plain lazy coder:


"I have a block of code with a bug. Bugs are bad. I know, I'll wrap it in

try:
    block
except:
    pass

and the bug will go away!"

It looks nice and requires relatively little typing. It seems like something
you should do, but it doesn't fix the problem, chances are it just makes it
worse. I've spotted many real-world examples where bare excepts mask the
presence of actual bugs, where the intention is clearly to catch a single
exception:

    try:
        return mylist[0]
    except:
        # empty list
        return None


Forcing people to type an exception will discourage such cowboy coding. If
the choice is between

    except BaseException:

instead of the lazy "except:" version, and

    except IndexError:

which do you think people will write?



> Also, I wish
> "BaseException" were just spelled "Exception", if it has to be used.

Most of the time, "catch everything" should mean catching Exception, not
BaseException. Broadly speaking, built-in exceptions which are
considered "errors" inherit from Exception, and the small number that don't
are used for some variation of control-flow:

StopIteration
GeneratorExit
KeyboardInterrupt
SysExit


Most of the time when people say "catch everything" they mean catch all
errors, i.e. Exception, rather than "don't let the user interrupt the code
using KeyboardInterrupt".

See also PEP 352:

http://www.python.org/dev/peps/pep-0352/

-- 
Steven

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


#88860

FromCameron Simpson <cs@zip.com.au>
Date2015-04-12 16:47 +1000
Message-ID<mailman.242.1428821229.12925.python-list@python.org>
In reply to#88854
On 12Apr2015 14:18, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
>On Sun, 12 Apr 2015 09:08 am, Cameron Simpson wrote:
>> Also, IMO, a bare "except:" syntax is far more pleasing to the eye than
>> "except magic_exception_name_that+gets_everything:".
>
>And that is exactly what makes bare excepts an attractive nuisance!
>
>I'm going to channel a newbie, cowboy or just plain lazy coder:
>"I have a block of code with a bug. Bugs are bad. I know, I'll wrap it in
>
>try:
>    block
>except:
>    pass
>
>and the bug will go away!"

And haven't we all seen that _many_ times on this list:-)

>It looks nice and requires relatively little typing. It seems like something
>you should do, but it doesn't fix the problem, chances are it just makes it
>worse.

And do not get me started on Makefiles which finish every compile command in 
"2>/dev/null" :-(

>I've spotted many real-world examples where bare excepts mask the
>presence of actual bugs, where the intention is clearly to catch a single
>exception: [...]
>Forcing people to type an exception will discourage such cowboy coding. If
>the choice is between
>
>    except BaseException:
>
>instead of the lazy "except:" version, and
>
>    except IndexError:
>
>which do you think people will write?

I fear that the just-beyond-beginner might write "Exception", but your point is 
well taken.

>> Also, I wish
>> "BaseException" were just spelled "Exception", if it has to be used.
>
>Most of the time, "catch everything" should mean catching Exception, not
>BaseException. Broadly speaking, built-in exceptions which are
>considered "errors" inherit from Exception, and the small number that don't
>are used for some variation of control-flow:
>
>StopIteration
>GeneratorExit
>KeyboardInterrupt
>SysExit
>
>Most of the time when people say "catch everything" they mean catch all
>errors, i.e. Exception, rather than "don't let the user interrupt the code
>using KeyboardInterrupt".

Yes, I see that this is true.

And I have special pain in some of my code which then causes me to specificly 
catch NameError ahead of my bare (or mostly bare) excepts because that usually 
indicates some stupid typo on my part, causing silent breakage and debugging 
hell. Ghastly.

>See also PEP 352:
>http://www.python.org/dev/peps/pep-0352/

Thank you for this.

Cheers,
Cameron Simpson <cs@zip.com.au>

To be or not to be?    Not to be.
        - John Slater (Arnold Schwartzenegger),
          _Macbeth_ (_The_Last_Action_Hero_)

[toc] | [prev] | [standalone]


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


csiph-web