[Python-Dev] PEP 550 v4

Nick Coghlan ncoghlan at gmail.com
Wed Aug 30 02:40:23 EDT 2017


On 30 August 2017 at 10:18, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
> On Tue, Aug 29, 2017 at 7:36 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> [..]
>>> For (1) we want the context change to be isolated.  For (2) you say
>>> that the context change should propagate to the caller.
>>
>>
>> No, I'm saying that the context change should *always*
>> propagate to the caller, unless you do something explicit
>> within the generator to prevent it.
>>
>> I have some ideas on what that something might be, which
>> I'll post later.
>
> BTW we already have mechanisms to always propagate context to the
> caller -- just use threading.local() or a global variable.  PEP 550 is
> for situations when you explicitly don't want to propagate the state.

Writing an "update_parent_context" decorator is also trivial (and will
work for both sync and async generators):

    def update_parent_context(gf):
        @functools.wraps(gf):
        def wrapper(*args, **kwds):
            gen = gf(*args, **kwds):
            gen.__logical_context__ = None
            return gen
        return wrapper

The PEP already covers that approach when it talks about the changes
to contextlib.contextmanager to get context changes to propagate
automatically.

With contextvars getting its own module, it would also be
straightforward to simply include that decorator as part of its API,
so folks won't need to write their own.

While I'm not sure how much practical use it will see, I do think it's
important to preserve the *ability* to transparently refactor
generators using yield from - I'm just OK with such a refactoring
becoming "yield from update_parent_context(subgen())" instead of the
current "yield from subgen()" (as I think *not* updating the parent
context is a better default than updating it).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list