Context manager able to write to the caller's namespace

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Jan 18 23:48:35 EST 2018


I'm looking for a solution, or at least hints, to this problem.

I want to define a context manager in one module:

# a.py
def CM:
    def __enter__(self):
        return self
    def __exit__(self, *args):
        pass



Then call it from another module:

# b.py
import a
with a.CM() as spam:
    x = 1
    y = 2


in such a way that the spam context manager can, on exit, see the callers 
namespace and write to it. E.g. as a toy example (this isn't what I 
actually want to do!) we might have this:

with a.CM() as spam:
    x = 1
print(x)
# prints 2, not 1

I stress that's not the intended functionality, it just demonstrates the 
requirement.

Don't assume that the content manager is going to be called in the global 
scope. In fact, the most common use I'm expecting is to call it from 
inside a class:

class Aardvark:
    with a.CM() as spam:
        x = 1

It's okay if it doesn't work inside a function:

def foo():
    with a.CM() as spam:
        x = 1
    assert x == 2


since function scopes in CPython are weird.

Any suggestions?



-- 
Steve




More information about the Python-list mailing list