pep-567: Rejected Ideas, Token usability, fixes (#511)

This commit is contained in:
Yury Selivanov 2017-12-13 17:06:41 -05:00 committed by GitHub
parent 75fe7fe8b8
commit 5a43c3b83a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 55 additions and 8 deletions

View File

@ -16,7 +16,7 @@ Abstract
This PEP proposes a new ``contextvars`` module and a set of new This PEP proposes a new ``contextvars`` module and a set of new
CPython C APIs to support context variables. This concept is 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. correctly keeping track of values per asynchronous task, e.g.
``asyncio.Task``. ``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 to be removed from the context if they were not in it before the
``set()`` call. ``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 contextvars.Context
------------------- -------------------
@ -463,7 +457,7 @@ Implementation Notes
using Hash Array Mapped Tries (HAMT). They allow for O(log N) using Hash Array Mapped Tries (HAMT). They allow for O(log N)
``set`` operation, and for O(1) ``get_context()`` function, where ``set`` operation, and for O(1) ``get_context()`` function, where
*N* is the number of items in the dictionary. For a detailed *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 * ``ContextVar.get()`` has an internal cache for the most recent
value, which allows to bypass a hash lookup. This is similar value, which allows to bypass a hash lookup. This is similar
@ -489,6 +483,51 @@ Summary of the New APIs
context. 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 Backwards Compatibility
======================= =======================
@ -501,6 +540,14 @@ code unmodified, but will automatically enable support for
asynchronous code. 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 Copyright
========= =========