Expand the try-expect syntax to support conditional expect block

Hello, I was thinking of a way to expand the current try-expect block to support condinitial expect block. I was imagining the new syntax as try: expression block expect Exception if condition expression block where the expect expression block would only run if the condition is met else it would raise the exception, for example the following code try: config = get_config() except Exception: if use_default: config = default else: raise would be converted to try: config = get_config() except Exception if use_default: config = default I find it very useful and also I found the same pattern in the following packages that were installed on my system. more_itertools/more.py:227 cloudinit/net/__init__.py:364 matplotlib/__init__.py:330 google/protobuf/internal/containers.py:126 networkx/algorithms/connectivity/edge_augmentation.py:296 twisted/internet/pollreactor.py:160 pyqtgraph/opengl/shaders.py:257 setuptools/_vendor/pyparsing.py:2191 setuptools/sandbox.py:253 pip/_internal/utils/misc.py:115 urllib3/poolmanager.py:362 mako/util.py:65 serial/serialposix.py:294 PIL/PngImagePlugin.py:335 click/core.py:1472 numpy/core/memmap.py:216 pyparsing.py:2067 Looking forward to hear some feedback, Regards

Awesome! never seen this syntax used before and the above libraries are not using it. Can you elaborate on the else part ? Why is it needed for the syntax to be correct and could you put any expression in the parenthesis ?

It's Python's conditional expression, `expression_true if condition else expression_false`. It's the same thing as C's ternary: `condition ? expression_true : expression_false` Also yes, you could put any expression in the parentheses. Just that the empty one is actually just an empty tuple.

19.05.22 09:45, nadav.misgav@gmail.com пише:
Awesome! never seen this syntax used before and the above libraries are not using it.
Can you elaborate on the else part ? Why is it needed for the syntax to be correct and could you put any expression in the parenthesis ?
https://docs.python.org/3/reference/expressions.html#conditional-expressions The tricky part is that isinstance(obj, ()) and issubclass(cls, ()), and corresponding internal check used in the `except ()` clause always return False. It is not explicitly stated (unlike to all() and any()), but it follows from the description if you read it carefully.

You probably already saw the syntax but it is not common in the "except" part: For example, the following: catch_everything = True try: raise Exception() except Exception if catch_everything else (): print("Caught!") It is the same as: catch_everything = True exception_to_catch = Exception if catch_everything else () try: raise Exception() except exception_to_catch: print("Caught!") Basically the argument for the "except" keyword can be a variable and therefore dynamic in nature. The () is because "except" accepts a tuple of exception classes and () is the empty tuple so it is accepted. On Thu, May 19, 2022 at 06:45:59AM -0000, nadav.misgav@gmail.com wrote:

On Wed, May 18, 2022 at 12:24 PM Serhiy Storchaka <storchaka@gmail.com> wrote:
That's an interesting idea I haven't seen before, but it doesn't work if the condition you want to test depends on the exception object, which in my experience it often does. Some of OP's examples are of that form: for instance, in setuptools/sandbox.py: try: ... except SystemExit as v: if v.args and v.args[0]: raise # Normal exit, just return In pip/_internal/utils/misc.py: try: os.makedirs(path) except OSError as e: # Windows can raise spurious ENOTEMPTY errors. See #6426. if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: raise I suppose the right way to implement it would be to support PEP 622 patterns in except clauses. except case SystemExit(args=args) if not args or not args[0]: pass # Normal exit, just return except case OSError(errno = errno.EEXIST | errno.ENOTEMPTY): # Windows can raise spurious ENOTEMPTY errors. See #6426. pass

I believe this would make the code more legible. Serhiy's take is very confusing to me (I get it, but don't think one should write like to get this behavior).

On Fri, Jun 03, 2022 at 06:43:59PM -0000, Nadav Misgav wrote:
should I try to implement this? seems there is some acceptance
If you want to experiment with an implementation just for your own pleasure, then go ahead. Or if you think that the implementation is trivial and simple, and a working implementation will strengthen the case for this proposal. But I think it is too early for you to spend many hours working on an implementation. As a syntax change, this will need a PEP before it can be accepted, and before you waste time writing a PEP you need a core developer sponsor. If you think that the feedback in this thread is sufficient to justify it, you can ask for a sponsor here and on the Python-Dev mailing list. -- Steve

03.06.22 21:43, Nadav Misgav пише:
should I try to implement this? seems there is some acceptance
No core developer supported this feature. My example shows that there is a problem with the proposed syntax. It is too similar to the existing valid syntax, it will confuse both people and the compiler. Even if the current parser is able to handle this, we should not abuse this, because it will still look ambiguous to people and diagnostic of syntax errors will be very hard.

Awesome! never seen this syntax used before and the above libraries are not using it. Can you elaborate on the else part ? Why is it needed for the syntax to be correct and could you put any expression in the parenthesis ?

It's Python's conditional expression, `expression_true if condition else expression_false`. It's the same thing as C's ternary: `condition ? expression_true : expression_false` Also yes, you could put any expression in the parentheses. Just that the empty one is actually just an empty tuple.

19.05.22 09:45, nadav.misgav@gmail.com пише:
Awesome! never seen this syntax used before and the above libraries are not using it.
Can you elaborate on the else part ? Why is it needed for the syntax to be correct and could you put any expression in the parenthesis ?
https://docs.python.org/3/reference/expressions.html#conditional-expressions The tricky part is that isinstance(obj, ()) and issubclass(cls, ()), and corresponding internal check used in the `except ()` clause always return False. It is not explicitly stated (unlike to all() and any()), but it follows from the description if you read it carefully.

You probably already saw the syntax but it is not common in the "except" part: For example, the following: catch_everything = True try: raise Exception() except Exception if catch_everything else (): print("Caught!") It is the same as: catch_everything = True exception_to_catch = Exception if catch_everything else () try: raise Exception() except exception_to_catch: print("Caught!") Basically the argument for the "except" keyword can be a variable and therefore dynamic in nature. The () is because "except" accepts a tuple of exception classes and () is the empty tuple so it is accepted. On Thu, May 19, 2022 at 06:45:59AM -0000, nadav.misgav@gmail.com wrote:

On Wed, May 18, 2022 at 12:24 PM Serhiy Storchaka <storchaka@gmail.com> wrote:
That's an interesting idea I haven't seen before, but it doesn't work if the condition you want to test depends on the exception object, which in my experience it often does. Some of OP's examples are of that form: for instance, in setuptools/sandbox.py: try: ... except SystemExit as v: if v.args and v.args[0]: raise # Normal exit, just return In pip/_internal/utils/misc.py: try: os.makedirs(path) except OSError as e: # Windows can raise spurious ENOTEMPTY errors. See #6426. if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: raise I suppose the right way to implement it would be to support PEP 622 patterns in except clauses. except case SystemExit(args=args) if not args or not args[0]: pass # Normal exit, just return except case OSError(errno = errno.EEXIST | errno.ENOTEMPTY): # Windows can raise spurious ENOTEMPTY errors. See #6426. pass

I believe this would make the code more legible. Serhiy's take is very confusing to me (I get it, but don't think one should write like to get this behavior).

On Fri, Jun 03, 2022 at 06:43:59PM -0000, Nadav Misgav wrote:
should I try to implement this? seems there is some acceptance
If you want to experiment with an implementation just for your own pleasure, then go ahead. Or if you think that the implementation is trivial and simple, and a working implementation will strengthen the case for this proposal. But I think it is too early for you to spend many hours working on an implementation. As a syntax change, this will need a PEP before it can be accepted, and before you waste time writing a PEP you need a core developer sponsor. If you think that the feedback in this thread is sufficient to justify it, you can ask for a sponsor here and on the Python-Dev mailing list. -- Steve

03.06.22 21:43, Nadav Misgav пише:
should I try to implement this? seems there is some acceptance
No core developer supported this feature. My example shows that there is a problem with the proposed syntax. It is too similar to the existing valid syntax, it will confuse both people and the compiler. Even if the current parser is able to handle this, we should not abuse this, because it will still look ambiguous to people and diagnostic of syntax errors will be very hard.
participants (8)
-
Andre Delfino
-
Ben Rudiak-Gould
-
Jeremiah Gabriel Pascual
-
Martin Di Paola
-
Nadav Misgav
-
nadav.misgav@gmail.com
-
Serhiy Storchaka
-
Steven D'Aprano