[Python-Dev] Py3k: Except clause syntax

Nick Coghlan ncoghlan at gmail.com
Sat Mar 18 04:47:05 CET 2006

Oleg Broytmann wrote:
> On Fri, Mar 17, 2006 at 07:44:51PM +0000, John J Lee wrote:
>> Perhaps parentheses around the exception list should be mandatory for the 
>> 2-or-more exceptions case?
>> except NameError as e:                  --> fine
>> except (NameError) as e:                --> fine
>> except (NameError,) as e:               --> fine
>> except NameError, OtherError as e:      --> SyntaxError
>> except (NameError, OtherError) as e:    --> fine
>    If parens are mandatory what is the difference from the current syntax?
> Why do we need "as" here? Why not stay with
> except (NameError, OtherError), e:

Currently the comma is used for two very different purposes within the same 
clause, so it's far too easy to make the mistake:

   except NameError, OtherError:

and then have to deal with the fact that OtherError isn't caught (and given 
how often unit tests fail to cover all error cases, it wouldn't be unusual for 
this bug to escape a unit testing regime, too).

If this code is made to "do the right thing", then there needs to be some 
other syntax to indicate the name that should be used for the value of the 
caught exception.

"as" is already used as an embedded naming syntax in two places:

   - import statements use it for "locate an object or module using one name, 
but bind it to a different name in this module"
     In this case, the binding is restricted to a single name and is applied 
individually to each element of a comma separated list:

     import foo as a, bar as b, baz as c

   - with statements use it for "retrieve the context manager for this context 
and bind the result of the manager's __enter__ method to this name"
     In this case, the binding may be either a single name or a tuple of 
names, and the expression itself is limited to a single term - parentheses are 
required around both comma separated lists and unpacking to separate names is 

     with (foo, bar, baz) as (a, b, c): pass
     with (foo, bar, baz) as x: pass

The proposal to use it for except clauses encounters a subtle difference - in 
the except clause, even if multiple exception types are listed in the clause, 
there is still only a single exception value to be bound to the name. The list 
of exception names merely limits the possible types for that exception, rather 
than their names.

So, as a somewhat novel approach, what about putting the "as" *before* the 
list of exceptions types? After all, the thing being bound is the exception 
caught, not the possible list of types:

  except NameError, OtherError:  # Exception value not bound

  except as ex, NameError, OtherError: # Exception value bound to ex

I don't actually have a problem with simply tacking the clause on the end 
(with or without mandatory parentheses) but figured I'd throw this idea out as 
an option. I'm not sure whether the parallel with "print" and "print >> 
stream," is a positive or a negative, though. . .


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

More information about the Python-Dev mailing list