From 5a43c3b83ab93638d6c4346973e6f63ee51386ec Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Wed, 13 Dec 2017 17:06:41 -0500 Subject: [PATCH] pep-567: Rejected Ideas, Token usability, fixes (#511) --- pep-0567.rst | 63 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/pep-0567.rst b/pep-0567.rst index abfdef9aa..7778b86bb 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 storage (TLS), but, unlike TLS, it allows +similar to thread-local storage (TLS), but, unlike TLS, it also allows correctly keeping track of values per asynchronous task, e.g. ``asyncio.Task``. @@ -174,12 +174,6 @@ and the ``ContextVar.reset(token)`` method, allows context variables to be removed from the context if they were not in it before the ``set()`` call. -Token API allows to get around having a ``ContextVar.delete()`` -method, which is incompatible with chained contexts design of -:pep:`550`. Future compatibility with :pep:`550` is desired -(at least for Python 3.7) in case there is demand to support -context variables in generators and asynchronous generators. - contextvars.Context ------------------- @@ -463,7 +457,7 @@ Implementation Notes using Hash Array Mapped Tries (HAMT). They allow for O(log N) ``set`` operation, and for O(1) ``get_context()`` function, where *N* is the number of items in the dictionary. For a detailed - analysis of HAMT performance please refer to :pep:`550`. + analysis of HAMT performance please refer to :pep:`550` [1]_. * ``ContextVar.get()`` has an internal cache for the most recent value, which allows to bypass a hash lookup. This is similar @@ -489,6 +483,51 @@ Summary of the New APIs context. +Design Considerations +===================== + +Why contextvars.Token and not ContextVar.unset()? +------------------------------------------------- + +The Token API allows to get around having a ``ContextVar.unset()`` +method, which is incompatible with chained contexts design of +:pep:`550`. Future compatibility with :pep:`550` is desired +(at least for Python 3.7) in case there is demand to support +context variables in generators and asynchronous generators. + +The Token API also offers better usability: the user does not have +to special-case absence of a value. Compare:: + + token = cv.get() + try: + cv.set(blah) + # code + finally: + cv.reset(token) + +with:: + + _deleted = object() + old = cv.get(default=_deleted) + try: + cv.set(blah) + # code + finally: + if old is _deleted: + cv.unset() + else: + cv.set(old) + + +Rejected Ideas +============== + +Replication of threading.local() interface +------------------------------------------ + +Please refer to :pep:`550` where this topic is covered in detail: [2]_. + + Backwards Compatibility ======================= @@ -501,6 +540,14 @@ code unmodified, but will automatically enable support for asynchronous code. +References +========== + +.. [1] https://www.python.org/dev/peps/pep-0550/#appendix-hamt-performance-analysis + +.. [2] https://www.python.org/dev/peps/pep-0550/#replication-of-threading-local-interface + + Copyright =========