[Python-Dev] PEP 463: Exception-catching expressions

Nick Coghlan ncoghlan at gmail.com
Thu Feb 27 13:57:31 CET 2014


On 27 February 2014 20:44, Ronald Oussoren <ronaldoussoren at mac.com> wrote:
>
> On 27 Feb 2014, at 11:09, Chris Angelico <rosuav at gmail.com> wrote:
>
>> On Thu, Feb 27, 2014 at 7:44 PM, Ronald Oussoren <ronaldoussoren at mac.com> wrote:
>>> What about (also mentioned in the PEP)?
>>>
>>>  value = (expr except Exception try default)
>>>
>>> This seems to read nicely, although "try" is at a completely different position than it is in the equivalent try statement.
>>>
>>> I like the general idea, but like Brett I don't like using a colon here at all.
>>
>> I see your "although" clause to be quite a strong objection. In the
>> statement form of an if, you have:
>
> I'm not convinced that this is a strong objection. The order of keywords is different, but that doesn't have to be problem.

As Chris notes, the problem is that if you use "try", the two
plausible interpretations are:

1. Evaluates left-to-right, try introduces a different part of the
syntax (different from every past statement->expression conversion
where the clauses are reordered, but almost always introduced by the
same keywords as they are in the statement form)
2. Evaluates right-to-left, try introduces the expressions covered by
the exception handler (this is just backwards, and significantly
harder to follow than even the "middle first" conditional expression)

Neither interpretation is particularly acceptable, and the fact that
the other interpretation would remain plausible regardless is a
further strike against both of them.

Personally, I think the PEP makes a good case for particular semantics
with a spelling that isn't great, but isn't completely abhorrent
either. I definitely think it represents an improvement over the
status quo, which is an ongoing proliferation of function-based
special cases for doing particular kinds of exception handling as an
expression, and the spelling advocated for in the PEP seems like the
best of the (many) alternatives that have been proposed.

The way I get the colon in the proposed syntax to make sense to my
brain is to view it as being more like the colon in a dictionary
key:value pair than it is like the one that introduces a suite or the
body of a lambda expression:

    (lst[2] except {IndexError: "No value"})

The analogy isn't exact (since exception handling is isinstance()
based rather than equality based), but I think it gives the right
general flavour in terms of the intended meaning of the colon in this
construct. The analogy could likely be encouraged and strengthened by
changing the parentheses requirements to make this read more like a
binary except expression with a parenthesised RHS rather than a
ternary expression:

    lst[2] except (IndexError: "No value")

Catching multiple errors would involve a parenthesised tuple as the "key":

    f() except ((TypeError, AttributeError): "No value")

The deferred "multiple except clauses" part of the PEP could also
change to be more dict display like:

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

Writing out those examples, I actually like that version (where the
parentheses are still mandatory, but the left paren is after the
except keyword rather than before the first expression) better than
the one currently in the PEP. It also avoids the weirdly unbalanced
look of the variant that had the left paren *before* the except
keyword. The main downside I see is that the exception handling
definition syntax would only be permitted in that specific location,
but still look a lot like an ordinary parenthesised expression.

Cheers,
Nick.

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


More information about the Python-Dev mailing list