[Python-Dev] PEP 567 pre v3

Guido van Rossum guido at python.org
Mon Jan 8 18:47:33 EST 2018


I am +1 on everything Yury says here.

On Mon, Jan 8, 2018 at 11:34 AM, Yury Selivanov <yselivanov.ml at gmail.com>
wrote:

> Hi,
>
> Thanks to everybody participating in the PEP 567 discussion!  I want
> to summarize a few topics to make sure that we are all on the same
> page (and maybe provoke more discussion).
>
>
> 1. Proposal: ContextVar has default set to None.
>
> From the typing point of view that would mean that if a context
> variable is declared without an explicit default, its type would be
> Optional.  E.g. say we have a hypothetical web framework that allows
> to access the current request object through a context variable:
>
>   request_var: ContextVar[Optional[Request]] = \
>       ContextVar('current_request')
>
> When we need to get the current request object, we would write:
>
>   request: Optional[Request] = request_var.get()
>
> And we'd also need to explicitly handle when 'request' is set to None.
> Of course we could create request_var with its default set to some
> "InvalidRequest" object, but that would complicate things.  It would
> be easier to just state that the framework always sets the current
> request and it's a bug if it's not set.
>
> Therefore, in my opinion, it's better to keep the current behaviour:
> if a context variable was created without a default value,
> ContextVar.get() can raise a LookupError.
>
>
> 2. Context.__contains__, Context.__getitem__ and ContexVar.default
>
> So if we keep the current PEP 567 behaviour w.r.t. defaults,
> ContextVar.get() might return a different value from Context.get():
>
>     v = ContextVar('v', default=42)
>     ctx = contextvars.copy_context()
>
>     ctx.get(v)   # returns None
>     v.get()   # returns 42
>     v in ctx  # returns False
>
> I think this discrepancy is OK.  Context is a mapping-like object and
> it reflects the contents of the underlying _ContextData mapping
> object.
>
> ContextVar.default is meant to be used only by ContextVar.get().
> Context objects should not use it.
>
> Maybe we can rename ContextVar.get() to ContextVar.lookup()?  This
> would help to avoid potential confusion between Context.get() and
> ContextVar.get().
>
>
> 3. Proposal: Context.get() and __getitem__() should always return up
> to date values.
>
> The issue with the current PEP 567 design is that PyThreadState points
> to a _ContextData object, and not to the current Context.  The
> following code illustrates how this manifests in Python code:
>
>     v = ContextVar('v')
>
>     def foo():
>         v.set(42)
>         print(v.get(), ctx.get(v, 'missing'))
>
>     ctx = Context()
>     ctx.run(foo)
>
> The above code will print "42 missing", because 'ctx' points to an
> outdated _ContextData.
>
> This is easily fixable if we make PyThreadState to point to the
> current Context object (instead of it pointing to a _ContextData).
> This change will also make "contextvars.copy_context()" easier to
> understand--it will actually return a copy of the current context that
> the thread state points to.
>
> Adding a private Context._in_use attribute would allow us to make sure
> that Context.run() cannot be simultaneously called in two OS threads.
> As Nathaniel points out, this will also simplify cache implementation
> in ContextVar.get().  So let's do this.
>
>
> 4. Add Context.copy().
>
> I was actually going to suggest this addition myself.  With the
> current PEP 567 design, Context.copy() can be implemented with
> "ctx.run(contextvars.copy_context)", but this is very cumbersome.
>
> An example of when a copy() method could be useful is capturing the
> current context and executing a few functions with it using
> ThreadPoolExecutor.map().  Copying the Context object will ensure that
> every mapped function executes in its own context copy (i.e.
> isolated).  So I'm +1 for this one.
>
>
> 5. PEP language.
>
> I agree that PEP is vague about some details and is incorrect in some
> places (like calling Context objects immutable, which is not really
> true, because .run() can modify them). I'll fix the language in v3
> once I'm back home.
>
>
> Yury
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/
> guido%40python.org
>



-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180108/2609efb2/attachment.html>


More information about the Python-Dev mailing list