[Python-ideas] except expression

Steven D'Aprano steve at pearwood.info
Sun Feb 16 04:35:02 CET 2014


On Sun, Feb 16, 2014 at 12:35:59AM +0000, MRAB wrote:
> On 2014-02-15 23:46, Chris Angelico wrote:
> >On Sun, Feb 16, 2014 at 10:17 AM, Greg Ewing
> ><greg.ewing at canterbury.ac.nz> wrote:
> >>>This does look a tiny bit like a function call, especially if you delete
> >>>the space between the leading expression and the opening bracket:
> >>>
> >>>    # ugly, don't do this
> >>>    things[i](except IndexError: 42)
> >>
> >>
> >>Yes, that's why I'm leaning towards the paren-less version.
> >
> >I'm not liking the parenthesized version here, because the 'except'
> >expression has to know how much of the preceding expression to modify.

I don't think this is terribly different from the if-expression. The 
parser sees an expression:

    1/x ...

and doesn't know it is part of an if-expression until it has read on and 
seen the "if":

    1/x if x != 0 ...

so I don't expect this to be a problem.


[...]
> >Parens could go around the whole thing:

Of course they can, that's just normal parentheses-as-grouping :-)


> >(thing[i] except IndexError: 42)
> >(1/x if x else "Div by 0")
> >
> >but not around the except clause:
> >
> >thing[i] (except IndexError: 42) # Nope
> >1/x (if x else "Div by 0") # Nope

I disagree about prohibiting this. I think it actually makes it easier 
to read in the case of multiple except terms. Since they ought to be 
separated by commas, and stylistically they ought to be split 
one-per-line, I prefer the bracket-less version when there is only a 
single except:

    thing(a, b) except ThisError, ThatError: default

and brackets when there are more than one:

    thing(a, b) (except ThisError, ThatError: default,
                 except SpamError, EggsError: something,
                 except OutOfCheeseError: different_thing,
                 )


although I'm happy for the parens to be optional in the second case if 
the parser can manage it, assuming that the parser can disambigulate all 
the various uses of commas.

I can't think of any places where parens are explicitly prohibited. They 
used to be prohibited in imports, but that's no longer the case. One 
should always be allowed to use parens for grouping and implicit line 
continuations, nearly everywhere.


How does this suggested syntax look with Raymond's recent example? 
Raymond regretted that max and min now take a "default" argument, as of 
Python 3.4. Let's compare:

    result = max(some_numbers, key=foo, default=float('nan'))

    result = max(some_numbers, key=foo) except ValueError: float('nan')


Looks damn good to me!


> >Incidentally, I'm looking at this being able to chain quite nicely:
> >
> >((expr except Exception1: default1) except Exception2: default2)

This is equivalent to:


try:
    try:
        result = expr
    except Exception1:
        result = default1
except Exception2:
    result = default2


> You'll also need to note that:
> 
>     ((expr except Exception1: default1) except Exception2: default2)
> 
> is not the same as:
> 
>     (expr except Exception1: default1 except Exception2: default2)

I disklike the lack of comma between except clauses. I think that ought 
to be written as:

    (expr except Exception1: default1, except Exception2: default2)

modulo the above argument about parentheses.


> The first will also catch Exception2 if default1 raises it, whereas the
> second will catch Exception2 only if expr raises it and it hasn't been
> caught by the preceding 'except'.

Correct. The two are quite different.


> >Ideally the peephole optimizer could set up a single try/except
> >structure for both, but syntactically, I'm seeing this as the way the
> >operator associates.
> >
> >I've mailed the first-draft PEP to peps@; is it appropriate to post it
> >here as well, or should I wait to hear back from peps@?

I think it is perfectly appropriate to post a draft PEP here.



-- 
Steven


More information about the Python-ideas mailing list