[Python-ideas] chained try (was Re: "maybe import"?)

spir denis.spir at gmail.com
Sun Dec 29 10:41:19 CET 2013


On 12/28/2013 09:05 PM, Andrew Barnert wrote:
> On Dec 28, 2013, at 8:10, Chris Angelico <rosuav at gmail.com> wrote:
>
>> There is one thing, though, that I'm seeing of all this. Exception
>> throwing is asymmetrical: you can attempt a series of statements until
>> one fails, but there's no convenient syntax to attempt a series of
>> statements until one succeeds. I wonder, could the more general case
>> be solved? Is there a way to, without stupid stuff like eval, wrap up
>> a few statements so they can be executed in a loop:
>>
>> def import_any(statement_list):
>>     for try_me in statement_list:
>>         try:
>>             # uhh, this is the bit I'm not sure about...
>>             try_me() # this would work if they're functions instead!
>>             return
>>         except ImportError:
>>             pass
>>     raise ImportError
>>
>> This works for a set of functions, but not for a bunch of "from this
>> import that" statements. Would it be worth mangling the top of your
>> script until it can be done with importlib or __import__? Doesn't seem
>> nearly as clean, somehow.
>
> This is a clever idea.
>
> If you could work out a clean syntax for the "try until one works" syntax, it would solve a wider range of problems than just this import issue.
>
> It strikes me that there's some similarity with if/elif/else. Maybe just:
>
>      try:
>          stuff
>      except try:
>          other stuff
>      except try:
>          different stuff
>      except Exception as e:
>          deal with it
>
> But there are a lot of open questions. First, "except try" looks horrible, but I can't think of anything better.

I would buy (if cheap!):

     try:
         stuff
     else try:
         other stuff
     else try:
         different stuff
     except Exception as e:
         deal with it

> If they all fail, do you only get the last exception, or are they all chained together?

Same issue in parsing in front of a choice (ordered or not): when match fails, 
what helpful error message? The parser cannot know which branch should have 
matched, so the only solution is to list failure causes of every branch; but 
branches may hold choices themselves, etc...

expected: p = a | b| c
at position: ....
found: ...

     expected: a = ...
     at position: ....
     found: ...

     expected: b = x | y
     at position: ....
     found: ...

         expected: x = ...
         at position: ....
         found: ...

         expected: y = ...
         at position: ....
         found: ...

     expected: c = ...
     at position: ....
     found: ...

This suggests that a general pattern for such an (ordered) choice of potential 
actions should not be modeled after exception catching; except (sic) for the 
failure branch in case none of them runs. My solution in parsing is only giving 
a general error (the first block above), but providing a solution (a test check 
tool func, the building block of test suites) for the user to try each potential 
branch individually (easily, quickly, and with helpful feedback).
	pat.check(str)

> Would there be a use for a sequence like this without except on the end (so if they all fail, it just raises)? Can you put an exception type or tuple between the "except try"? What about an as clause (so the block could use it)?

I would require the general failure branch in syntax, for safety, like ordinary; 
with the same contents contents beeing the same: "pass" or "assert False". [1]

Denis

[1] I take the opportunity to ask: is there a builtin exception or other means 
to say "this block should never be reached"?



More information about the Python-ideas mailing list