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
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