Hi Stephan,

On Fri, Jun 23, 2017 at 6:23 AM, Stephan Houben <stephanh42@gmail.com> wrote:
Hi Andy,

What you propose is essentially the "try .. catch .. in" construct as
described for Standard ML in:

​It's not really a proposal. It's existing syntax. I was suggesting a way to implement the example that would catch an IndexError raised by accessing elements in bah but not those raised by foo.

 

https://pdfs.semanticscholar.org/b24a/60f84b296482769bb6752feeb3d93ba6aee8.pdf

Something similar for Clojure is at:
https://github.com/rufoa/try-let

So clearly this is something more people have struggled with.
The paper above goes into deep detail on the practical and (proof-)theoretical
advantages of such a construct.

Stephan

​A​ndy

 

2017-06-23 1:47 GMT+02:00 Andy Dirnberger <dirn@dirnonline.com>:
>
>
>> On Jun 22, 2017, at 7:29 PM, Cameron Simpson <cs@zip.com.au> wrote:
>>
>>> On 23Jun2017 06:55, Steven D'Aprano <steve@pearwood.info> wrote:
>>>> On Thu, Jun 22, 2017 at 10:30:57PM +0200, Sven R. Kunze wrote:
>>>> We usually teach our newbies to catch exceptions as narrowly as
>>>> possible, i.e. MyModel.DoesNotExist instead of a plain Exception. This
>>>> works out quite well for now but the number of examples continue to grow
>>>> where it's not enough.
>>>
>>> (1) Under what circumstances is it not enough?
>>
>> I believe that he means that it isn't precise enough. In particular, "nested exceptions" to me, from his use cases, means exceptions thrown from within functions called at the top level. I want this control too sometimes.
>>
>> Consider:
>>
>>   try:
>>       foo(bah[5])
>>   except IndexError as e:
>>       ... infer that there is no bah[5] ...
>>
>> Of course, it is possible that bah[5] existed and that foo() raised an IndexError of its own. One might intend some sane handling of a missing bah[5] but instead silently conceal the IndexError from foo() by mishandling it as a missing bah[5].
>>
>> Naturally one can rearrange this code to call foo() outside that try/except, but that degree of control often leads to quite fiddly looking code with the core flow obscured by many tiny try/excepts.
>>
>> One can easily want, instead, some kind of "shallow except", which would catch exceptions only if they were directly raised from the surface code; such a construct would catch the IndexError from a missing bah[5] in the example above, but _not_ catch an IndexError raised from deeper code such within the foo() function.
>>
>> Something equivalent to:
>>
>>   try:
>>       foo(bah[5])
>>   except IndexError as e:
>>       if e.__traceback__ not directly from the try..except lines:
>>           raise
>>       ... infer that there is no bah[5] ...
>>
>> There doesn't seem to be a concise way to write that. It might not even be feasible at all, as one doesn't have a way to identify the line(s) within the try/except in a form that one can recognise in a traceback.
>
> How about something like this?
>
>     try:
>         val = bah[5]
>     except IndexError:
>         # handle your expected exception here
>     else:
>         foo(val)
>>
>>
>> Cheers,
>> Cameron Simpson <cs@zip.com.au>
>> _______________________________________________
>> 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/