[Python-ideas] Improving Catching Exceptions

Nick Coghlan ncoghlan at gmail.com
Wed Jun 28 09:26:02 EDT 2017


On 28 June 2017 at 21:48, Sven R. Kunze <srkunze at mail.de> wrote:
> As it was snipped away, let me ask again:
>
> I don't see how this helps differentiating shallow and nested exceptions
> such as:
>
> try:
>     with exception_guard(ImportError):
>         import myspeciallib
> except RuntimeError: # catches shallow and nested ones
>     import fallbacks.MySpecialLib as myspeciallib

There are two answers to that:

1. In 3.3+ you can just catch ImportError, check "exc.name", and
re-raise if it's not for the module you care about

2. There's a reasonable case to be made that importlib should include
an ImportError -> RuntimeError conversion around the call to
loader.exec_module (in the same spirit as PEP 479). That way, in:

    try:
        import myspeciallib
    except ImportError:
        import fallbacks.MySpecialLib as myspeciallib

any caught ImportError would relate to "myspeciallib", while uncaught
ImportErrors arising from *executing* "myspeciallib" will be converted
to RuntimeError, with the original ImportError as their __cause__.

So it would make sense to file an RFE against 3.7 proposing that
behavioural change (we couldn't reasonably do anything like that with
the old `load_module()` importer API, as raising ImportError was how
that API signalled "I can't load that". We don't have that problem
with `exec_module()`).

> At least in my tests, exception_guard works this way and I don't see any
> improvements to current behavior. Moreover, I am somewhat skeptical that
> using this recipe will really improve the situation. It's a lot of code
> where users don't have any stdlib support. I furthermore doubt that all
> Python coders will now wrap their properties using the guard. So, using
> these properties we will have almost no improvement. I still don't see it as
> the responsibility of coder of the property to guard against anything.
> Nobody is forced to catch exceptions when using a property.

Honestly, if folks are trying to write complex Python code without
using at least "pylint -E" as a static check for typos in attribute
names (regardless of whether those lines get executed or not), then
inadvertently hiding AttributeError in property and __getattr__
implementations is likely to be the least of their problems. So
pylint's structural checks, type analysis tools like MyPy, or more
advanced IDEs like PyCharm are typically going to be a better option
for folks wanting to guard against bugs in their *own* code than
adding defensive code purely as a cross-check on their own work.

The cases I'm interested in are the ones where you're either
developing some kind of framework and you need to code that framework
defensively to guard against unexpected failures in the components
you're executing (e.g. exec_module() in the PEP 451 import protocol),
or else you're needing to adapt between two different kinds of
exception reporting protocol (e.g. KeyError to AttributeError and
vice-versa).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list