[Python-ideas] Proposal: Allowing any variable to be used in a 'with... as...' expression

Chris Angelico rosuav at gmail.com
Sat May 18 22:01:21 EDT 2019


On Sun, May 19, 2019 at 11:46 AM David Mertz <mertz at gnosis.cx> wrote:
>>
>> I think you probably mean something other than what you actually write.  It doesn't really make sense for "any expression" as far as I can tell.  What would it possibly mean to write:
>>
>> with (2+2) as foo:
>>     print(foo)
>
>
> I have occasionally thought it would be nice to do something like this (and I could, but I haven't, so I guess I don't think it that strongly):
>
> >>> @contextmanager
> ... def bind(val):
> ...     yield val
> ...
> >>> with bind(2+2) as four:
> ...     print(four)
> ...
> 4
>

Thing is, this is slightly deceptive. People will assume/expect that
the name binding 'four' ends at the end of the 'with' block. In actual
fact, something like this has an entrance but no exit - there is
absolutely no meaning to the unindent. Functionality would be
identical to "with bind(2+2) as four: pass" followed by the same code.

Python's 'with' block guards a section of code. At the end of that
code, something has to get undone - a file gets closed, a database
transaction gets committed/rolled back, a suppressed exception returns
to normal state, etc. You can't have the __exit__ method do "del
four", so with current code, there's no code-significant meaning to
this block.

So there are two broad options:

1) Keep it having no functional meaning, just a semantic declaration
"hey, this is the only place I'm using this". Not hugely valuable, but
maybe people would like it. Probably best to have the three-line
bind() function.

2) Redefine the 'with' block or create a new syntactic form such that
the variable actually creates a subscope. That way, at the end of the
block, the name would revert to its former meaning.

x = 1
with local 2 as x:
    print(x) # 2
print(x) # 1

This would have definite value, but would be a much larger change to
the language. And variants of it have been proposed and rejected
before.

ChrisA


More information about the Python-ideas mailing list