
Hi Jim, In short, yes, we can "dumb down" PEP 550 to a chain of maps. PEP 550 does the following on top of that dumbed down version: 0. Adds execution_context "chain" root to PyThreadState. 1. Extends (async-)generator objects to support this chaining -- each generator has its own "env" to accumulate its changes. 2. ContextKey is an object that we use to work with EC. Compared to using strings, using an object allows us to implement caching (important for numpy and decimal-like libs) and avoids name clashes. 3. Yes, efficiency is important. If you start an asyncio.Task, or schedule an asyncio callback, or want to run some code in a separate OS thread, you need to capture the current EC -- make a shallow copy of all LCs in it. That's expensive, and the PEP solves this problem by using special datastructures (a), and providing just enough APIs to work with the EC so that those datastructures are not exposed to the end user (b). 4. Provides common APIs that will be used by asyncio, decimal, numpy, etc.
(A) The current mapping is available through a series of sys.* calls. (why not a builtin? Or at least a global, injected when a different environment is needed?)
This was never proposed :) I decided to put new APIs to the sys module as we usually are conservative about adding new globals, and the feature is low-level (like working with frames).
If the semantics are right, and collections.ChainMap is rejected only for efficiency, please say so in the PEP.
`collections.ChainMap` on its own is not a solution, it's one of possible implementations. Efficiency is indeed the reason why using ChainMap is not an option (see (3) above). This whole "capturing of execution context" topic is not covered well enough in the PEP, and is something that we'll fix in the next version (soon). Yury