[Python-ideas] except expression

Chris Angelico rosuav at gmail.com
Tue Feb 18 21:55:56 CET 2014


On Wed, Feb 19, 2014 at 3:06 AM, Chris Angelico <rosuav at gmail.com> wrote:
> I'm currently working on finding a bunch of examples from the stdlib
> that could be translated. Will post them once I get the script sorted
> out. As it's currently 3AM, though, that means I need to fry up some
> bacon or something before I continue :)

Alright, results are in.

Script:
https://github.com/Rosuav/ExceptExpr/blob/master/find_except_expr.py
Output:
https://github.com/Rosuav/ExceptExpr/blob/master/candidates.txt
Annotated examples:
https://github.com/Rosuav/ExceptExpr/blob/master/examples.py

The last one is the most readable. I've collected up a bunch of viable
candidates for translation. (Note that I'm not advocating going
through and editing these files for no other reason. That'd just be
code churn. But these are cases where, had this feature existed when
that code was written, it could have been taken advantage of.)

My script is currently _very_ simplistic. It looks *only* for
assignments, so it won't find something like this:

try:
    foo.append(args[0])
except IndexError:
    foo.append('')

which is correct, because it's impossible to know whether foo.append()
will raise IndexError. (Chances are it won't, especially if we know
foo is a list, for instance.) It's not safe to directly translate that
sort of thing. It might, however, be something worth improving, as it
narrows the scope of the except clause. But if that same code is
written thus:

try:
    tmp = args[0]
except IndexError:
    tmp = ''
foo.append(tmp)

then the script _will_ find it, and then it really is a candidate for editing.

Point to note: Apart from one instance, where it wasn't being used
anyway, I found not a single instance of 'as' being used. There was
one case where sys.exc_info() was referenced, though, so this may just
mean that the stdlib files in question are maintaining compatibility
with old versions of Python.

I didn't look at most of the tests. The script found 195 plausible
try/except blocks, of which 37 have the word "test" in the name;that
leaves 158 that are likely to benefit from this change. There are a
couple of false positives, but not many.

Next is to figure out what else is a candidate for editing. Here's my
current criteria, straight from the docstring:

"""Report on 'simple' try/except statements.

The definition of simple is:
1. No else or finally clause
2. Only one except clause (currently)
3. Exactly one statement in the try clause
4. Exactly one statement in each except clause
5. Each of those statements is the same type.
6. That type is one that could be an expression.
7. Those statements are all compatible.

The last two are the trickiest. Currently I'm looking
only for assignments, where both try and except assign
to the same target. This is, however, too narrow."""

Interestingly, removing criterion 2 gives us three additional examples
out of the test suite, and nothing else. There are no cases outside of
the test suite that look like this:

try:
    x = some_calculation
except ValueError:
    x = something_else
except OverflowError:
    x = different_thing

(The test suite has one case with those exact two exceptions, and a
pair that use OverflowError and ZeroDivisionError. In each case,
they're comparing two actions to make sure they give the same result,
where "throwing OverflowError" is a result like any other.)

Conclusions: The need for chained exception catching might not be so
great after all, and even the 'as' keyword isn't as (heh heh)
important as I thought it was.

Alternate conclusion: My sample is too small. Need more. Data, you
have the helm.

ChrisA


More information about the Python-ideas mailing list