[Python-Dev] PEP 463: Exception-catching expressions

Chris Angelico rosuav at gmail.com
Thu Feb 27 22:29:53 CET 2014

I've added another utility script to my PEP draft repo:


It's built out of some pretty horrendous hacks, it makes some
assumptions about code layout (eg spaces for indentation, and a
try/except block never has anything else on the same line(s)), and the
code's a bit messy, but it does work. I ran it on the Python stdlib
and it produced a whole lot of edits (I had it keep the old version in
comments, bracketed with markers with the text "PEP 463" in them,
which makes it easy to find and analyze); one file (with two try
blocks) causes a test failure, but all the rest still pass.

If people can try the script on their own codebases and see how it
looks, that'd be great. I recommend first running the script with
ast.Expr handling removed (as per the file you see above), and then
maybe running it with that one line commented out. You'll get a lot of
unhelpful change suggestions from the double-expression handler.

Could a core committer please apply the last few changes to the PEP?


or the diff is below. I think this is the last important change left;
things have gone fairly quiet here, and I think the PEP's about ready
to request pronouncement, unless someone knows of something I've
forgotten. (Have I said "I'll write up a paragraph about that" about
anything and not done it yet? Now's the perfect time to remind me.)



diff -r 5f63c8a92d1c pep-0463.txt
--- a/pep-0463.txt Mon Feb 24 14:22:46 2014 -0800
+++ b/pep-0463.txt Fri Feb 28 08:25:33 2014 +1100
@@ -43,6 +43,34 @@

 * statistics.mean(data) - no way to handle an empty iterator

+Had this facility existed early in Python's history, there would have been
+no need to create dict.get() and related methods; the one obvious way to
+handle an absent key would be to respond to the exception.  One method is
+written which signal the absence in one way, and one consistent technique
+is used to respond to the absence.  Instead, we have dict.get(), and as of
+Python 3.4, we also have min(... default=default), and myriad others.  We
+have a LBYL syntax for testing inside an expression, but there is currently
+no EAFP notation; compare the following::
+    # LBYL:
+    if key in dic:
+        process(dic[key])
+    else:
+        process(None)
+    # As an expression:
+    process(dic[key] if key in dic else None)
+    # EAFP:
+    try:
+        process(dic[key])
+    except KeyError:
+        process(None)
+    # As an expression:
+    process(dic[key] except KeyError: None)
+Python generally recommends the EAFP policy, but must then proliferate
+utility functions like dic.get(key,None) to enable this.

@@ -338,6 +366,19 @@
     except KeyError:
         u = tarinfo.uid

+Look up an attribute, falling back on a default::
+    mode = (f.mode except AttributeError: 'rb')
+    # Lib/aifc.py:882:
+    if hasattr(f, 'mode'):
+        mode = f.mode
+    else:
+        mode = 'rb'
+    return (sys._getframe(1) except AttributeError: None)
+    # Lib/inspect.py:1350:
+    return sys._getframe(1) if hasattr(sys, "_getframe") else None
 Perform some lengthy calculations in EAFP mode, handling division by
 zero as a sort of sticky NaN::

@@ -616,7 +657,7 @@
 it would be with the statement form, and as its syntax is a point on
 which consensus has not been reached, the entire feature is deferred.

-Multiple 'except' keywords can be used, and they will all catch
+Multiple 'except' keywords could be used, and they will all catch
 exceptions raised in the original expression (only)::

     # Will catch any of the listed exceptions thrown by expr;

-- end --

More information about the Python-Dev mailing list