[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