[Python-ideas] PEP 572: Assignment Expressions (post #4)

Chris Angelico rosuav at gmail.com
Thu Apr 12 09:41:49 EDT 2018


On Thu, Apr 12, 2018 at 11:31 PM, Jacco van Dorp <j.van.dorp at deonet.nl> wrote:
> 2018-04-12 15:02 GMT+02:00 Nick Coghlan <ncoghlan at gmail.com>:
>> On 12 April 2018 at 22:22, Jacco van Dorp <j.van.dorp at deonet.nl> wrote:
>>> I've looked through PEP 343, contextlib docs (
>>> https://docs.python.org/3/library/contextlib.html ), and I couldn't
>>> find a single case where "with (y := f(x))" would be invalid.
>>
>> Consider this custom context manager:
>>
>>     @contextmanager
>>     def simple_cm():
>>         yield 42
>>
>> Given that example, the following code:
>>
>>     with cm := simple_cm() as value:
>>         print(cm.func.__name__, value)
>>
>> would print "'simple_cm 42", since the assignment expression would
>> reference the context manager itself, while the with statement binds
>> the yielded value.
>>
>> Another relevant example would be `contextlib.closing`: that returns
>> the passed in argument from __enter__, *not* self.
>>
>> And that's why earlier versions of PEP 572 (which used the "EXPR as
>> NAME" spelling) just flat out prohibited top level name binding
>> expressions in with statements: "with (expr as name):" and "with expr
>> as name:" were far too different semantically for the only syntactic
>> difference to be a surrounding set of parentheses.
>>
>> Cheers,
>> Nick.
>
> Makes sense. However, couldn't you prevent that by giving with
> priority over the binding ? As in "(with simple_cm) as value", where
> we consider the "as" as binding operator instead of part of the with
> statement ? Sure, you could commit suicide by parenthesis, but by
> default it'd do exactly what the "with simple_cm as value" currently
> does. This does require use of as instead of :=, though. (which was
> the point I was trying to make, apologies for the confusion)

If you want this to be a generic name-binding operation, then no; most
objects cannot be used as context managers. You'll get an exception if
you try to use "with 1 as x:", for instance.

As Nick mentioned, there are context managers that return something
other than 'self', and for those, "with expr as name:" has an
important meaning that cannot easily be captured with an assignment
operator.

ChrisA


More information about the Python-ideas mailing list