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
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
=========