Raymond Hettinger | 29 Aug 2012 07:15
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


New submission from Raymond Hettinger:

It is a somewhat common pattern to write:

   try:
       do_something()
   except SomeException:
       pass

To search examples in the standard library (or any other code base) use:

    $ egrep -C2 "except( [A-Za-z]+)?:" *py  | grep -C2 "pass"

In the Python2.7 Lib directory alone, we find 213 examples.

I suggest a context manager be added that can ignore specifie exceptions.  Here's a possible implementation:

class Ignore:
    ''' Context manager to ignore particular exceptions'''

    def __init__(self, *ignored_exceptions):
        self.ignored_exceptions = ignored_exceptions

    def __enter__(self):
        return self

    def __exit__(self, exctype, excinst, exctb):
        return exctype in self.ignored_exceptions

(Continue reading)

Alex Gaynor | 29 Aug 2012 07:17
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Changes by Alex Gaynor <alex.gaynor <at> gmail.com>:

----------
nosy: +alex

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Raymond Hettinger | 29 Aug 2012 07:35
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Raymond Hettinger added the comment:

Hmm, the __exit__ method was doing exact matches by exception type, so KeyError wouldn't match
LookupError or Exception.

There are probably a number of ways to fix this, but it may be easiest to use the builtin exception catching mechanisms:

class Ignore:
    ''' Context manager to ignore particular exceptions'''

    def __init__(self, *ignored_exceptions):
        self.ignored_exceptions = ignored_exceptions

    def __enter__(self):
        return self

    def __exit__(self, exctype, excinst, exctb):
        if exctype is not None:
            try:
                raise
            except self.ignored_exceptions:
                return True

----------

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
(Continue reading)

Alex Gaynor | 29 Aug 2012 07:55
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Alex Gaynor added the comment:

Why not just: issubclass(exctype, self.exception_types)?

----------

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Raymond Hettinger | 29 Aug 2012 08:06
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Raymond Hettinger added the comment:

Yes, something along those lines would be *much* better:

class Ignore:
    ''' Context manager to ignore particular exceptions'''

    def __init__(self, *ignored_exceptions):
        self.ignored_exceptions = ignored_exceptions

    def __enter__(self):
        return self

    def __exit__(self, exctype, excinst, exctb):
        return exctype and issubclass(exctype, self.ignored_exceptions)

----------

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Nick Coghlan | 29 Aug 2012 08:20
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Nick Coghlan added the comment:

I'd just write it with  <at> contextmanager. Making it easier to cleanly factor out exception handling is one of
the main reasons that exists.

   <at> contextmanager
  def ignored(*exceptions):
    """Context manager to ignore particular exceptions"""
    try:
        yield
    except exceptions:
        pass

While the class based version would likely be fractionally faster, the generator based version is more
obviously correct.

----------

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Chris Jerdonek | 29 Aug 2012 08:43
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Changes by Chris Jerdonek <chris.jerdonek <at> gmail.com>:

----------
nosy: +cjerdonek

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Ezio Melotti | 29 Aug 2012 09:28
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Ezio Melotti added the comment:

I think I'm -1 on this.

This saves two lines, but makes the code less explicit, it can't be used for try/except/else or
try/except/except, it requires an extra import, the implementation is simple enough that it doesn't
necessary need to be in the stdlib, it might encourage bad style, and it's slower.

Some of these downsides are indeed somewhat weak, but the upside of saving two lines is quite weak too IMHO.

----------
nosy: +ezio.melotti

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Martin v. Löwis | 29 Aug 2012 09:51
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Martin v. Löwis added the comment:

I think the zipfile example is really a bad example. IMO, it would
best be written as

try:
  return bool(EndRecData(fp))
except IOError:
  return False

i.e. there shouldn't be a pass statement at all in this code, and the if can be dropped whether you use
try-except or with.

----------
nosy: +loewis

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Chris Rebert | 29 Aug 2012 10:01
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Changes by Chris Rebert <pybugs <at> rebertia.com>:

----------
nosy: +cvrebert

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Nick Coghlan | 29 Aug 2012 11:55
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Nick Coghlan added the comment:

(Note: I'm not yet convinced this is a good idea. I'm definitely considering it, though)

As with many context managers, a key benefit here is in the priming effect for readers. In this code:

    try:
       # Whatever
    except (A, B, C):
       pass

the reader doesn't know that (A, B, C) exceptions will be ignored until the end. The with statement form
makes it clear before you start reading the code that certain exceptions won't propagate:

    with ignored(A, B, C):
        # Whatever

I'm not worried that it makes things less explicit - it's pretty obvious what a context manager called
"ignored" that accepts an arbitrary number of exceptions is going to do.

One other thing it does is interact well with ExitStack - you can stick this in the stack of exit callbacks to
suppress exceptions that you don't want to propagate.

----------

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
(Continue reading)

Ezio Melotti | 29 Aug 2012 12:07
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Ezio Melotti added the comment:

> As with many context managers, a key benefit here is 
> in the priming effect for readers.

The "focus" is mostly on what it's being executed rather than what it's being ignored though.

"Do this operation and ignore these exceptions if they occur"
vs.
"Ignore these exceptions if they occur while doing this operation."

> I'm not worried that it makes things less explicit - it's pretty
> obvious what a context manager called "ignored" that accepts an
> arbitrary number of exceptions is going to do.

It's still understandable, but while I'm familiar with the semantics of try/except, I wouldn't be sure if
e.g. this just ignored those specific exceptions or even their subclasses without checking the doc/code.

> One other thing it does is interact well with ExitStack - you can
> stick this in the stack of exit callbacks to suppress exceptions that
> you don't want to propagate.

This seems a good use case.

----------

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
(Continue reading)

Antoine Pitrou | 29 Aug 2012 12:51
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Antoine Pitrou added the comment:

If this is desirable then I think it would be better as a classmethod of Exception:

with KeyError.trap():
    do_something()

----------
nosy: +pitrou

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Eric V. Smith | 29 Aug 2012 13:08
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Eric V. Smith added the comment:

While the classmethod version has some appeal, it doesn't extend well to handling multiple exception types.

I'm -0 on this, in any event. I think the original code is more clear. Why force people to learn (or recognize)
a second idiom for something so simple?

----------
nosy: +eric.smith

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Jesús Cea Avión | 29 Aug 2012 13:38
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Changes by Jesús Cea Avión <jcea <at> jcea.es>:

----------
nosy: +jcea

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Roundup Robot | 11 Mar 2013 06:27
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Roundup Robot added the comment:

New changeset 406b47c64480 by Raymond Hettinger in branch 'default':
Issue #15806: Add contextlib.ignored().
http://hg.python.org/cpython/rev/406b47c64480

----------
nosy: +python-dev

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Raymond Hettinger | 11 Mar 2013 06:28
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Changes by Raymond Hettinger <raymond.hettinger <at> gmail.com>:

----------
resolution:  -> fixed
status: open -> closed

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Nick Coghlan | 11 Mar 2013 09:02
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Nick Coghlan added the comment:

FTR, Raymond and I discussed this on IRC and I gave it a +1 before he committed it.

The advantage the callable form has over a class method is that it readily scales to ignoring multiple
exception types in a single with statement.

----------

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org

Barry A. Warsaw | 16 Mar 2013 01:44
Favicon

[issue15806] Add context manager for the "try: ... except: pass" pattern


Changes by Barry A. Warsaw <barry <at> python.org>:

----------
nosy: +barry

_______________________________________
Python tracker <report <at> bugs.python.org>
<http://bugs.python.org/issue15806>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/python-python-bugs-list%40m.gmane.org


Gmane