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


Groups > comp.lang.python > #98139

Re: Modern recommended exception handling practices?

From Chris Angelico <rosuav@gmail.com>
Newsgroups comp.lang.python
Subject Re: Modern recommended exception handling practices?
Date 2015-11-03 18:52 +1100
Message-ID <mailman.8.1446537149.8789.python-list@python.org> (permalink)
References <52739457-5f7a-48ea-8835-9fc8934174f9@googlegroups.com> <56385887$0$1598$c3e8da3$5496439d@news.astraweb.com> <mailman.7.1446534982.8789.python-list@python.org> <563860b9$0$1589$c3e8da3$5496439d@news.astraweb.com>

Show all headers | View raw


On Tue, Nov 3, 2015 at 6:22 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> A lot can happen in the few microseconds between
> checking for the existence of the file and actually opening it -- the file
> could be renamed or deleted.

And a lot of microseconds can happen between two opcodes, too. Even
inside a Python script, it's possible for threads or other arbitrary
code execution to get in your way:

if "foo" in counters:
    # context switch here!
    process(counters["foo"])

Garbage collection can happen at any time. Here's an (admittedly
arbitrary) example of how the above could be broken:

>>> class X:
...     def __init__(self, name, dict):
...         self.dict = dict; self.name = name
...         self.dict[self.name] = 0
...     def frob(self):
...         self.dict[self.name] += 1
...     def __del__(self):
...         del self.dict[self.name]
...
>>> counters = {}
>>> x = X("foo", counters)
>>> x.refcycle = x
>>> counters
{'foo': 0}
>>> del x
>>> counters
{'foo': 0}
>>> gc.collect()
10
>>> counters
{}

If the cycle-detecting garbage collector happens to be called
immediately after the 'if', you'll get an exception.

So I suppose what you might do is this:

try:
    # Optimization: Since a lot of these names won't be
    # in the dict, we check first rather than relying on the
    # exception. Since counters get removed in the __del__
    # method, we can't depend 100% on the 'in' check,
    # but an unnecessary try block is cheap.
    if "foo" in counters:
        process(counters["foo"])
except KeyError:
    pass

But any time you need a block comment to justify your code, you'd
better be REALLY sure the performance benefit is worth the complexity.

For reliability, expect exceptions.

ChrisA

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


Thread

Modern recommended exception handling practices? vasudevram <vasudevram@gmail.com> - 2015-10-29 10:43 -0700
  Re: Modern recommended exception handling practices? Steven D'Aprano <steve@pearwood.info> - 2015-11-03 17:47 +1100
    Re: Modern recommended exception handling practices? Chris Angelico <rosuav@gmail.com> - 2015-11-03 18:16 +1100
      Re: Modern recommended exception handling practices? Steven D'Aprano <steve@pearwood.info> - 2015-11-03 18:22 +1100
        Re: Modern recommended exception handling practices? Chris Angelico <rosuav@gmail.com> - 2015-11-03 18:52 +1100
      Re: Modern recommended exception handling practices? Paul Rubin <no.email@nospam.invalid> - 2015-11-03 11:59 -0800

csiph-web