[Python-ideas] New PEP 550: Execution Context

Nick Coghlan ncoghlan at gmail.com
Tue Aug 15 06:49:53 EDT 2017


On 15 August 2017 at 05:25, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
> Nick, you nailed it with your example.
>
> In short: current PEP 550 defines Execution Context in such a way,
> that generators and iterators will interact differently with it. That
> means that it won't be possible to refactor an iterator class to a
> generator and that's not acceptable.
>
> I'll be rewriting the whole specification section of the PEP today.

Trying to summarise something I thought of this morning regarding
ec_back and implicitly isolating iterator contexts:

With the notion of generators running with their own private context
by default, that means the state needed to call __next__ on the
generator is as follows:

- current thread EC
- generator's private EC (stored on the generator)
- the generator's __next__ method

This means that if the EC manipulation were to live in the next()
builtin rather than in the individual __next__() methods, then this
can be made a general context isolation protocol:

- provide a `sys.create_execution_context()` interface
- set `__private_context__` on your iterable if you want `next()` to
use `ec.run()` (and update __private_context__  afterwards)
- set `__private_context__ = None` if you want `next()` to just call
`obj.__next__()` directly
- generators have __private_context__ set by default, but wrappers
like contextlib.contextmanager can clear it

That would also suggest that ec.run() will need to return a 2-tuple:

    def run(self, f: Callable, *args, **kwds) -> Tuple[Any, ExecutionContext]:
        """Run the given function in this execution context

        Returns a 2-tuple containing the function result and the
execution context
        that was active when the function returned.
        """

That way next(itr) will be able to update itr.__private_context__
appropriately if it was initially set and the call changes the active
context.

We could then give send(), throw() and their asynchronous counterparts
the builtin+protocol method treatment, and put the EC manipulation in
their builtins as well.

Anyway, potentially a useful option to consider as you work on
revising the proposal - I'll refrain from further comments until you
have an updated draft available :)

Cheers,
Nick.

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


More information about the Python-ideas mailing list