[Python-ideas] except expression

Ram Rachum ram at rachum.com
Thu Feb 13 14:26:01 CET 2014


My favorite syntax so far is:

    x except Exception pass y

    x except Exception as e pass e.y

As weird as it is to use pass this way, it's better than using return. It's
better than not having the exception immediately follow `except`, it's
better than using a colon, it's better than all the other possible
compromises we could make.


On Thu, Feb 13, 2014 at 3:19 PM, Philipp A. <flying-sheep at web.de> wrote:

> actually i like the first proposal, because it mirrors "the trinary":
>
> ```python
> 'spam' if mustard else 'eggs'
> eat() except SickException else puke()
> ```
>
> but it's a bit weird.
>
> I don't like `return` at all, because it's exclusively about returning
> from functions. `for` is for loops. And qhile from is used more versatile,
> it's even weirder than `else` here.
>
> I also don't like putting anythiing but the exception type after the
> `except`.
>
> It should definitely be `EXPR except EXC_TYPE [as EXC_NAME] KEYWORD
> ALT_EXPR`, with `EXC_NAME` being defined in `ALT_EXPR` and afterwards.
>
> and i'm leaning towards `pass` or `else` as `KEYWORD`. `pass` is only used
> to mean "do nothing" right now, and indeed that's fitting: it's just a
> border between `EXC_TYPE [as EXC_NAME]` and `ALT_EXPR`, and its other
> meaning makes sense in english grammar. Maybe even `try`? Like "use this,
> except if that doesn't work, then try using the other thing".
>
>
> 2014-02-13 13:50 GMT+01:00 Nick Coghlan <ncoghlan at gmail.com>:
>
> On 13 February 2014 20:10, M.-A. Lemburg <mal at egenix.com> wrote:
>> > On 13.02.2014 10:24, Nick Coghlan wrote:
>> >> General comment: like Raymond, I'm inclined to favour a nice expression
>> >> friendly exception handling syntax, precisely because of the
>> proliferation
>> >> of relatively ad hoc alternative solutions (in particular, the
>> popularity
>> >> of being able to pass in default values to handle empty iterables).
>> >
>> > Here's a variant the resembles the code you'd write in a helper
>> > function to achieve the same thing, only stripped down somewhat:
>> >
>> > x = something() except ValueError return default_value
>> >
>> > def try_something():
>> >     try:
>> >         return something()
>> >     except ValueError:
>> >         return default_value
>> >
>> > x = something() except ValueError as exc return exc.message
>> >
>> > def try_something():
>> >     try:
>> >         return something()
>> >     except ValueError as exc
>> >         return exc.message
>> >
>> > Obviously, having a keyword "use" would make a better fit :-)
>> >
>> > x = something() except ValueError use default_value
>>
>> Even if we don't agree on a resolution for 3.5, I think there's more
>> than enough interest for it to be worth someone's while to collate
>> some of the proposals in a PEP - if nothing else, it will save
>> rehashing the whole discussion next time it comes up :)
>>
>> The benefits of this:
>>
>> - the status quo is that various APIs are growing "default" parameters
>> to handle the case where they would otherwise throw an exception
>> - this is creating inconsistencies, as some such functions can be used
>> easily as expressions without risking any exception (those where such
>> a parameter has been added), as well as a temptation to use "Look
>> Before You Leap" pre-checks, even in cases where exception handling
>> would be a better choice
>> - sequence indexing is a case where there is no current standard
>> mechanism for providing a default value, so you're either use a
>> pre-check for the system length, or else using a full try statement or
>> context manager to handle the IndexError
>> - by providing a clean, expression level syntax for handling a single
>> except clause and providing an alternate value for the expression,
>> this problem could be solved once and for all in a systematic way,
>> rather than needing to incrementally change the API of a variety of
>> functions (as well as addressing the container subscripting case in a
>> way that doesn't require switching away from using the subscript
>> syntax to a normal function call, or switching from use an expression
>> to a statement)
>>
>>
>> Some of the specific syntactic proposals:
>>
>>     x = op() except default if Exception
>>     x = op() except default for Exception
>>     x = op() except default from Exception
>>     x = op() except Exception return default
>>
>>     x = op() except exc.attr if Exception as exc
>>     x = op() except exc.attr for Exception as exc
>>     x = op() except exc.attr from Exception as exc
>>     x = op() except Exception as exc return exc.attr
>>
>> The except/if construct has parser ambiguity issues. While they're
>> potentially solvable by requiring parens around conditional
>> expressions in that context, that would come at the cost of a
>> significant redesign of the language grammar.
>>
>> The except/for option reads quite nicely, but introduces a
>> substantially different meaning for "for".
>>
>> The except/from option reads OK when combined with "as" and actually
>> using the caught exception, but otherwise reads strangely.
>>
>> The except/return option looks like it should either introduce a new
>> scope or else return from the current function. The presence of the
>> "as exc" clause in all variants actually suggests a new scope could be
>> a good idea, given past experience with iteration variables in list
>> comprehensions.
>>
>> So, if we take the point of view that the new syntax is almost
>> *literally* a shorthand for:
>>
>>     def _helper(op, exc, make_default):
>>         try:
>>             return op()
>>         except exc:
>>             return make_default()
>>
>>     x = _helper(op, Exception, make_default)
>>
>> Then that would suggest the following syntax and interpretation:
>>
>>     op() except Exception pass
>>
>>     def _work_or_return_None():
>>         try:
>>             return op()
>>         except Exception:
>>             pass
>>     _work_or_return_None()
>>
>>     x = op() except Exception return value
>>
>>     def _work_or_return_default():
>>         try:
>>             return op()
>>         except Exception:
>>             return value
>>     x = _work_or_return_default()
>>
>>     x = op() except Exception as exc return exc.attr
>>
>>     def _work_or_process_exception():
>>         try:
>>             return op()
>>         except Exception as exc:
>>             return exc.attr
>>     x = _work_or_process_exception()
>>
>> OK, with the "introduces a new scope" caveat, consider me a fan of
>> MAL's syntax unless/until someone points out a potential flaw that I
>> have missed.
>>
>> A possible addition: allow "raise" in addition to "pass" and "return"
>> (for exception transformation as an expression)
>>
>> Cheers,
>> Nick.
>>
>> --
>> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
>> _______________________________________________
>> Python-ideas mailing list
>> Python-ideas at python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "python-ideas" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/python-ideas/ZoBGdwuH3uk/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> python-ideas+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140213/bc03bdb4/attachment.html>


More information about the Python-ideas mailing list