pep-567: Rejected Ideas, Token usability, fixes (#511)
This commit is contained in:
parent
75fe7fe8b8
commit
5a43c3b83a
63
pep-0567.rst
63
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
|
||||
=========
|
||||
|
||||
|
|
Loading…
Reference in New Issue