[Python-Dev] PEP 550 v4 (original) (raw)

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