[Python-ideas] ChainMap as a context manager

Nick Coghlan ncoghlan at gmail.com
Mon Aug 8 06:11:58 CEST 2011


On Mon, Aug 8, 2011 at 1:43 PM, dag.odenhall at gmail.com
<dag.odenhall at gmail.com> wrote:
> To be quite honest I'm not perfectly sure myself; it just seemed like
> such a natural context manager that I got curious if it was just
> overlooked or if I was missing something. If it turns out it would
> make sense it might be good to realize it early before the 3.3
> release?

While the enthusiasm is appreciated, it's useful to run through a
quick sanity check before lobbing an email into the inboxes of all of
the python-ideas subscribers:

1. Do I have a concrete use case in mind?
2. If yes, is that use case highly specific to my current problem
domain, or is it more broadly applicable than that?
3. If no, is there a clear inconsistency or wart that presents a
roadblock to learning the language that the idea would address?

We're actually fairly conservative about what we add to the core
language and the standard library, so we greatly prefer ideas that
have been "battle tested" outside the standard library first. Py3k did
include a couple of experiments that are still in the process of
proving themselves (i.e. function annotations and new-style string
formatting), but such changes are definitely the exception rather than
the rule.

In this case, it is trivial for someone to write a
collections.ChainMap based decorator that works as you describe:

@contextmanager
def scope(chain=None):
    if scope is None:
        yield ChainMap({})
    else:
        yield chain.new_child()

with scope() as outer:
    with scope(outer) as inner1:
        # Manipulate inner1 without affecting outer

However, that adds no real expressivity and is unlikely to be
particularly useful in practice, since most lexical scoping problems
can be handled using *actual* lexical scoping. ChainMap is useful for
cases like multiple levels of configuration data where the scoping
occurs at runtime rather than in the source code. Hiding a call
new_child() inside a context manager just to get an additional level
of indentation is fairly pointless.

Cheers,
Nick.

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



More information about the Python-ideas mailing list