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@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@gmail.com>:

On 13 February 2014 20:10, M.-A. Lemburg <mal@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@gmail.com   |   Brisbane, Australia
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


_______________________________________________
Python-ideas mailing list
Python-ideas@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@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.