[Python-ideas] except expression

Steven D'Aprano steve at pearwood.info
Wed Feb 19 01:43:57 CET 2014


On Tue, Feb 18, 2014 at 03:56:10PM +0000, Paul Moore wrote:
> On 18 February 2014 15:05, Chris Angelico <rosuav at gmail.com> wrote:
> >> Well, yes and no. There are only 2 out of the 10 syntaxes originally
> >> proposed in the PEP at the start of this thread that use a colon. I've
> >> already pointed out that I don't like a colon, so assume I said
> >> "except return 0" if you must :-)
> >
> > Whether it's a colon or another keyword, _something_ is necessary in
> > there, if it's permissible to specify an exception type:
> >
> > sum(x[3] except IndexError 0 for x in list_of_tuples)
> > sum(x[3] except 0 for x in list_of_tuples)
> >
> > How would you parse each of those, without a separator?
> 
> With "return" as a separator. I said that above. Was I not clear?

Yes you were clear, but this is a huge complicated thread and if Chris 
is the least bit like me, he's probably feeling a bit overloaded :-)

Using return to not actually return seems completely wrong to me. This 
is the problem with all the proposals to overload some arbitrary keyword 
*just because it is available*. To me, all of these are equally as 
arbitrary and silly:

    expression except return 42
    expression except pass 42
    expression except del 42
    expression except import 42
    expression except class 42

For each keyword in (return, pass, del, import, ...), we are attempting 
to overload it to mean something different inside an except expression 
to what it does outside of one.

With return and pass, if we squint and turn our heads to the side, we 
might be able to persuade ourselves that there is a vague analogy 
between what the keyword does outside of expression to what it does 
inside ("it returns from the expression, but not from the function" sort 
of thing). But I don't consider vague analogies to be a good enough 
reason to overload a keyword with two distinct uses.

Is anyone going to propose some other, new, keyword? Although the 
barrier to new keywords is high, it's not impossibly high. It's worth at 
least considering.


> I remain less than happy with the colon notation, although I will
> concede that the basic
> 
>     x[3] except IndexError: 0
> 
> form is not horrible - it just becomes horrible very, very fast when
> people try to do anything more complicated than that.

Really? I think adding a second exception to the same clause is not 
horrible at all.

    x[3] except IndexError, KeyError: 0

Parens around the exception list should be permitted, but I don't think 
they need to be mandatory:

    x[3] except (IndexError, KeyError): 0


If we allow multiple except clauses -- and I am +1 on that -- then it 
should be recommended to put one except clause per line, indented for 
clarity where needed:


my_values = [# existing syntax
             lambda a, b: (a+b)/(a*b),
             somelist[2:-1],
             {key: value for key in sequence},
             some_function(x) if x else -1, 
             # proposed new syntax
             (minmax(sequence) except ValueError: (-1, -1)),
             (str(x[3]) except IndexError, KeyError: 0,
                        except NameError: UNDEF,
                        except UnicodeDecodeError: '?',
                        ),
             ]


As you can see from my examples, using colons is hardly unheard of, and 
while multiple except clauses does make the except expression more 
complicated, the use of parens and sensible formatting allows you to 
digest it a bit at a time.

Of course people might abuse this. But they might abuse list comps, 
generator expressions, ternary if, and even mathematical expressions 
too. In practice we solve that by slapping them with a halibut :-) and 
saying "don't do that".



-- 
Steven


More information about the Python-ideas mailing list