From c1f434c437b610dadcca11c4170706e579abce22 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Tue, 12 Dec 2017 20:41:25 -0500 Subject: [PATCH] pep-567: More fixes (#504) --- pep-0567.rst | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/pep-0567.rst b/pep-0567.rst index 0c83f4f13..afe373eec 100644 --- a/pep-0567.rst +++ b/pep-0567.rst @@ -16,7 +16,7 @@ Abstract This PEP proposes a new ``contextvars`` module and a set of new CPython C APIs to support context variables. This concept is -similar to thread-local variables, but, unlike TLS, it allows +similar to thread-local storage (TLS), but, unlike TLS, it allows correctly keeping track of values per asynchronous task, e.g. ``asyncio.Task``. @@ -136,11 +136,11 @@ restore the ``ContextVar`` to its previous value, or remove it from the context if it was not set before. The ``ContextVar.reset(Token)`` is used for that:: - old = var.set(1) + token = var.set(1) try: ... finally: - var.reset(old) + var.reset(token) The ``Token`` API exists to make the current proposal forward compatible with :pep:`550`, in case there is demand to support @@ -155,7 +155,7 @@ like ``decimal`` and ``numpy``. contextvars.Context ------------------- -``Context`` objects are mappings of ``ContextVar`` to values. +``Context`` object is a mapping of context variables to values. To get the current ``Context`` for the current OS thread, use the ``contextvars.get_context()`` method:: @@ -180,9 +180,12 @@ be contained in the ``ctx`` context:: assert var.get() == 'ham' ctx = get_context() + + # Any changes that 'function' makes to 'var' will stay + # isolated in the 'ctx'. ctx.run(function) - assert var.get('spam') + assert var.get() == 'spam' Any changes to the context will be contained and persisted in the ``Context`` object on which ``run()`` is called on. @@ -218,8 +221,9 @@ keyword-only argument, which defaults to the current context:: # ... some time later context.run(callback, *args) -Tasks in asyncio need to maintain their own isolated context. -``asyncio.Task`` is modified as follows:: +Tasks in asyncio need to maintain their own isolated context that +they inherit from the point they were created at. ``asyncio.Task`` +is modified as follows:: class Task: def __init__(self, coro): @@ -378,6 +382,22 @@ points to a ``_ContextData`` object:: self.__used = False +Summary of the New APIs +======================= + +* A new ``contextvars`` module with ``ContextVar``, ``Context``, + and ``Token`` classes, and a ``get_context()`` function. + +* ``asyncio.Loop.call_at()``, ``asyncio.Loop.call_later()``, + ``asyncio.Loop.call_soon()``, and + ``asyncio.Future.add_done_callback()`` run callback functions in + the context they were called in. A new *context* keyword-only + parameter can be used to specify a custom context. + +* ``asyncio.Task`` is modified internally to maintain its own + isolated context. + + Backwards Compatibility =======================