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

Yonatan Zunger zunger at humu.com
Sat May 18 22:36:05 EDT 2019


I would definitely love that kind of subscoping syntax, but as you say,
that would be a much larger change. :)

The use of this for things like '2+2' would be, as you say, syntactic
sugar; the compiler could even be clever and strip it out of the bytecode
entirely. Its only purpose in that context would be to clarify place of
use, and to allow simplification of multi-element 'with' assignments like
in the last example I gave in the original email.

The principal purpose of this change, however, would be to enable things
like optional value returns, in which in at least one fork of a conditional
the 'with' statement would remain nontrivial.

On Sat, May 18, 2019 at 7:02 PM Chris Angelico <rosuav at gmail.com> wrote:

> 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
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20190518/72ea2aa9/attachment.html>


More information about the Python-ideas mailing list