`try with` Syntactic Sugar

I often find myself writing code like this:

try:
    with (...):
        ... do stuff ...
    # No code at the same indentation level of `with`
except ...:
    ... handle exception ...

The idea came that one whole level of indentation can be removed if try and with can be combined, like such:

try with (... context managers ...):
    ... do stuff ...
except ...:
    ... handle exception ...

Not essential, but IMHO kind of nice to have, as it saves 1 vertical line, and 4 horizontal space.

2 Likes

Why not shorten it further?

with (... context managers ...):
    ... do stuff ...
except ...:
    ... handle exception ...

Because in that construct except becomes optional.

By specifying it as try with it indicates that I want / have to handle the exception.

So if I type code like this:

with (... context managers ...):
    ... do stuff ...

It means I don’t expect anything bad to happen. But if I write it like this:

try with (... context managers ...):
    ... do stuff ...

I am fully aware bad things can probably happen and I must handle them.

Is this purely aesthetic or is there a problem that this syntax change could help solve?

I’m reminded of a related comment from another thread:

Admittedly, it’s purely aesthetic.

But saving 1 vertical line + 4 horizontal space is not trivial, especially since indentation is part and parcel of Python syntax.

Not sure how hard it will be to implement, I’ll be honest.

  • The structure itself is exactly the same as try...except structure
  • Only the parser for try needs to be changed. try_stmt construct will need a change like so:
try_stmt  ::=  try1_stmt | try2_stmt | try3_stmt
try1_stmt ::=  "try" ( with_stmt | ":" suite )
               ("except" [expression ["as" identifier]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]
  • Implementation wise, the compiler will need to emit code as a result of parsing with_stmt

Yes, linters will need to understand these changes, grabbing all target within the with_stmt construct to be able to validate code between the try with and except statements.

Minor quibble: It’s one vertical and one horizontal, if you’re counting Python syntax. The choice of how wide your horizontal indents are is entirely yours.

1 Like

Isn’t handling that exception something the context manager can take care of doing?
It is its context after all.

Or an extra context manager exception_handler_cm can be added that takes care of that.

with (exception_handler_cm, ... original context managers ...):
    ... do stuff ...

A context manager cannot do all of the things that can be done in an except block:

try:
    with f():
        g()
except Error:
    return h()

Well, I wouldn’t call that something that cannot be done, but something that cannot be written exactly that way. One could just store store that return value.