On 2/28/2014 12:41 AM, Chris Angelico wrote:
On Fri, Feb 28, 2014 at 6:38 PM, Glenn Linderman <v+python@g.nevcal.com> wrote:
Whereas the current PEP syntax has ambiguity regarding how to interpret
a-expr except except-list-b: b-expr except except-list-c: c-expr (does the
2nd except apply to a-expr or b-expr?), without parentheses, and, as far as
I am concerned, even with the parentheses, this syntax makes it very clear
that each of the Exception-lists apply to a-expr.
Fair enough. It's a bit hard to talk about multiple except
expressions, though, as they're a problem unless formally supported -
and they're almost never needed. Really, all you need to do is say
"never abut except-expressions without parentheses" (which the current
proposal and the "parens around the exception bit only" proposal both
enforce), and then there's no problem. I expect that normal use of
this won't include any form of chaining. Yes, it can - like any
feature - be used abnormally, but at some point it's better to just
drop it out as a statement.

Key advantage to others may be that because the : is within the () [and the
leading ( is quite nearby, making it obvious], it is less likely to be
considered a statement boundary, and more easily explained as a special type
of list syntax... not _really_ a list, because it is really code to be
executed somewhat sequentially rather than data, and lists don't have : ...
and not _really_ a dict constant, which does have :, because the Exception
is not _really_ a key, but the syntax can draw on analogies with the dict
constant syntax which will help people remember it, and even sort of
understand that there is a pair-wise relationship between the Exception-list
and the expression after the :, without repeating the except over and over.
See the confusing terminology we have here? It might be called a
"list" of except-expressions, but the brackets are round, and a list's
are square. It's kinda like dict syntax, only again, the other sort of
bracket, and it's wrong to try to construct a dict; it'd be too
tempting to conflate this with some of the other current proposals for
lazily-evaluated expressions (aka "simpler syntax for lambda" or other
terms). This is, fundamentally, a multi-part expression on par with
"and" and "or": first, evaluate the primary expression; then, if an
exception is raised, evaluate the exception list and see if it
matches; then, if it matches, squash the exception and evaluate the
default expression. You can't turn that into a dict, partly because
you'd need to sort out lazy evaluation, and partly because a dict is
unordered - if this is expanded to support multiple except clauses,
they have to be processed in order. (You might, for instance, catch
ZeroDivisionError, and then Exception, with different handling. It'd
be VERY confusing for them to be processed in the wrong order,
particularly if it happens unpredictably.)

That's why I kept saying "not _really_" :)  It isn't a list, but it has an order requirement; it isn't a dict, but it has pairs; and finally, it isn't data, but code.  But nonetheless the analogies are somewhat useful.

Are there any other expressions that allow parens around a part of the
expression, without the stuff inside them becoming a completely
separate sub-expression?

Sure. Function invocation.  You can claim (and it is accurate) that the stuff inside is somewhat independent of the actual function called, but the syntax is  function-name open-paren parameter-list close-paren, and the stuff in the parens would be a tuple if it were purely data, except not quite a tuple because some items are pairs (name and value), but it winds up being neither a tuple, nor a list, nor a dict, but instead a complex structure related to code execution :)  Actually, this sounds quite similar to

    value = expr except (
        Exception1: default1,
        Exception2: default2,
        Exception3: default3,

except that to get the pairing aspect of some parameters for a function call, you use = instead of :, and instead of a named function it has an expression and a keyword.
Not being an expert parser generator, I don't know if the () could be made optional if there is only one exception-list, but that would also remove one of the benefits some folks might perceive with using this syntax, and would also make the analogy with function call syntax a little less comparable.