[Python-ideas] except expression

Jan Kaliszewski zuo at chopin.edu.pl
Sun Feb 16 13:01:00 CET 2014


16.02.2014 00: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.
[snip]

That's why what a proposed was: things[i] except (IndexError: 42)
-- rather than: things[i] (except IndexError: 42).

Also, see below...


> Parens could go around the whole thing:
>
> (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
>
> Incidentally, I'm looking at this being able to chain quite nicely:
>
> ((expr except Exception1: default1) except Exception2: default2)
[snip]

In terms of my proposal it would clearly be just:

     expr except (Exception1: default1) except (Exception2: default2)

Of course grouping parens could be added without changing semantics:

     (expr except (Exception1: default1)) except (Exception2: default2)

Also, see below...


15.02.2014 19:11, Steven D'Aprano wrote:

> On Sat, Feb 15, 2014 at 11:20:13AM +1300, Greg Ewing wrote:
>> Here's another one:
>>
>>    things[i] (except IndexError: 42)
>
> I believe Jan Kaliszewski independently came up with the same syntax
> earlier, which is a good sign. Two people suggesting the same thing 
> is
> promising.

Indeed, though please note that my proposal is a bit different:

     things[i] except (IndexError: 42)

possibly extendable to:

     # with 'as' clause'
     some_io() except (OSError as exc: exc.errno)

...and/or:

     # with multiple exception catches
     some_io() except (FileNotFoundError: 42,
                       OSError as exc: exc.errno)

Before I posted the proposal I did think about the "things[i] (except
..." variant also but I don't like that the opening parenthesis
character suggest to a human reader that it is a call...  On the other
hand, when the parenthesis is *after* the 'except' keyword it is clear
for human readers that it is a dedicated syntax having nothing to do
with a call.

Also, for a multiple-exception-catches-variant I don't like repeating
the 'except' keyword for each catch, as well as the ambiguity whether
the consecutive 'except...' concerns only the initial expression or
also the preceding 'except...').  In my proposal there is no such
ambiguity.

I also believe that making the parens *obligatory* is a good thing as
then:

* things are much more clear when several expressions are combined
   (e.g. except-expression + conditional expression; except-expression
   + another except-expression, except-expression +
   generator-expression...);

* it is clear that the colon has nothing to do with opening a code
   block;

* it just reads better than without parens.


More complex (though probably not very realistic) example:

     msg = (cache[k] except (
                LookupError: backend.read() except (
                    OSError: 'resource not available'))
            if check_permission(k)
            else 'access not allowed'
           ) except (Exception: 'internal error occurred')


Cheers.
*j



More information about the Python-ideas mailing list