Re: [Python-Dev] [ssl] The weird case of IDNA

2018-01-02 Thread Ronald Oussoren


> On 31 Dec 2017, at 18:07, Nathaniel Smith  wrote:
> 
> On Dec 31, 2017 7:37 AM, "Stephen J. Turnbull" 
>  > wrote:
> Nathaniel Smith writes:
> 
>  > Issue 1: Python's built-in IDNA implementation is wrong (implements
>  > IDNA 2003, not IDNA 2008).
> 
> Is "wrong" the right word here?  I'll grant you that 2008 is *better*,
> but typically in practice versions coexist for years.  Ie, is there no
> backward compatibility issue with registries that specified IDNA 2003?
> 
> Well, yeah, I was simplifying, but at the least we can say that always and 
> only using IDNA 2003 certainly isn't right :-). I think in most cases the 
> preferred way to deal with these kinds of issues is not to carry around an 
> IDNA 2003 implementation, but instead to use an IDNA 2008 implementation with 
> the "transitional compatibility" flag enabled in the UTS46 preprocessor? But 
> this is rapidly exceeding my knowledge.
> 
> This is another reason why we ought to let users do their own IDNA handling 
> if they want…

Do you know what the major browser do w.r.t. IDNA support? If those 
unconditionally use IDNA 2008 is should be fairly safe to move to that in 
Python as well because that would mean we’re less likely to run into backward 
compatibility issues.

Ronald

___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Guido van Rossum
Oh, the "Specification" section in the PEP is too brief on several of these
subjects. It doesn't really specify what var.get() does if the value is not
set, nor does it even mention var.get() except in the code
examples for var.reset(). It's also subtle that ctx[var] returns the
default (if there is one). I suppose it will raise if there isn't one --
resulting in the somewhat surprising behavior where `var in ctx` may be
true but `ctx[var]` may raise. And what does it raise? (All these questions
are answered by the code, but they should be clearly stated in the PEP.)

I would really like to invite more people to review this PEP! I expect I'll
be accepting it in the next two weeks, but it needs to go through more
rigorous review.

On Thu, Dec 28, 2017 at 4:48 PM, Victor Stinner 
wrote:

> NLe 28 déc. 2017 11:20 AM, "Nathaniel Smith"  a écrit :
>
> On Thu, Dec 28, 2017 at 1:51 AM, Victor Stinner
>  wrote:
> > var = ContextVar('var', default=42)
> >
> > and:
> >
> > var = ContextVar('var')
> > var.set (42)
> >
> > behaves the same, no?
>
> No, they're different. The second sets the value in the current
> context. The first sets the value in all contexts that currently
> exist, and all empty contexts created in the future.
>
>
> Oh, that's an important information. In this case, "default" is the best
> name.
>
> The PEP may be more explicit about the effect on all contexts. Proposition
> of documentation:
>
> "The optional *default* parameter is the default value in all contexts. If the
> variable is not set in the current context, it is returned by by
> context[var_name] and by var.get(), when get() is called without the
> default parameter."
>
> Victor
>
> ___
> Python-Dev mailing list
> [email protected]
> 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)
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Unique loader per module

2018-01-02 Thread Barry Warsaw
We have what I think is one last design question for importlib.resources.

https://gitlab.com/python-devs/importlib_resources/issues/49

The problem is that the ResourceReader ABC omits the package from the function 
signatures, so that on a compatible loader, you only need to specify the 
resource you are interested in.

This is fine for file loaders because every package will have a unique loader 
instance associated with it, so it will know which package the requested 
resource is homed to.

But AFAICT, there is no specification or requirement in Python that every 
module/package have a unique loader instance.  In fact, it’s not unreasonable 
given some of the text in PEP 302 to think that loader instances can be shared. 
 The PEP says "In many cases the finder and loader can be one and the same 
object: finder.find_module() would just return self” and you aren’t going to 
typically have a unique finder per module, so that would implied a shared 
loader per finder.

We even have an existence proof in the zip importer:

>>> import test.test_importlib.zipdata02
>>> import sys, os
>>> sys.path.insert(0, 
>>> os.path.join(os.path.dirname(test.test_importlib.zipdata02.__file__), 
>>> 'ziptestdata.zip'))
>>> import ziptestdata.two
>>> import ziptestdata.one
>>> ziptestdata.one.__spec__.loader == ziptestdata.two.__spec__.loader
True

The issue above proposes two solutions.  The first is to change the ABC so that 
it includes the package argument in the ABC method signatures.  That way, a 
shared loader will know which package the requested resource is relative to.

Brett doesn’t like this, for several reasons (quoting):

1. redundant API in all cases where the loader is unique to the module
2. the memory savings of sharing a loader is small
3. it's implementation complexity/overhead for an optimization case.

The second solution, and the one Brett prefers, is to reimplement zip importer 
to not use a shared loader.  This may not be that difficult, if for example we 
were to use a delegate loader wrapping a shared loader.

The bigger problem IMHO is two-fold:

1. It would be backward incompatible.  If there’s any code out there expecting 
a shared loader in zipimport, it would break
2. More problematic is that we’d have to impose an additional requirement on 
loaders - that they always be unique per module, contradicting the advice in 
PEP 302

The reason for this is third party finder/loaders.  Sure, we can fix zipimport 
but any third party finder/loaders could have the same problem, and they’d be 
within their rights given the current specification.  We’d have to prohibit 
that, or at least say that any third party finder/loaders that shared their 
loader can’t implement ResourceReader (which would be the practical effect 
anyway).  I think that would be a shame.

So while I agree with Brett that it’s uglier, and that once we decide we’re 
essentially locked into the API, I don’t see a whole lot of options.

Thoughts, feedback, suggestions are welcome.
-Barry



signature.asc
Description: Message signed with OpenPGP
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] 'continue'/'break'/'return' inside 'finally' clause

2018-01-02 Thread Neil Schemenauer
Serhiy Storchaka  wrote:
> Currently 'break' and 'return' are never used inside 'finally'
> clause in the stdlib.

See the _recv_bytes() function:

Lib/multiprocessing/connection.py: 316

> I would want to see a third-party code that uses them.

These are the only ones I found so far:

./gevent/src/gevent/libev/corecffi.py: 147
./gevent/src/gevent/threadpool.py: 226

I have an AST walker script that finds them.

Regards,

  Neil
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Victor Stinner
> I would really like to invite more people to review this PEP! I expect
I'll be accepting it in the next two weeks, but it needs to go through more
rigorous review.

I read again the PEP and I am still very confused by Context.run().

The PEP states multiple times that a context is immutable:

* "read-only mapping"
* inherit from Mapping, not from MutableMapping

But run() does modify the context (or please correct me if I
completely misunderstood
the PEP! I had to read it 3 times to check if run() mutates or not the
context).

It would help if the ctx.run() example in the PEP would not only test
var.get() but also test ctx.get(var). Or maybe show that the variable value
is kept in a second function call, but the variable is "restored" between
run() calls.

The PEP tries hard to hide "context data", which is the only read only
thing in the whole PEP, whereas it's a key concept to understand the
implementation.

I understood that:

* _ContextData is immutable
* ContextVar.set() creates a new _ContextData and sets it in the current
Python thread state
* When the called function completes, Context.run() sets its context data
to the new context data from the Python thread state: so run() does modify
the "immutable" context


The distinction between the internal/hiden *immutable* context data and
public/visible "mutable" (from my point of view) context is unclear to me
in the PEP.

The concept of "current context" is not defined in the PEP. In practice,
there is no "current context", there is only a "current context data" in
the current Python thread. There is no need for a concrete context instance
to store variable variables values. It's also hard to understand that in
the PEP.


Why Context could not inherit from MutableMapping? (Allow ctx.set(var,
value) and ctx [var] = value.) Is it just to keep the API small: changes
should only be made using var.set()?

Or maybe Context.run() should really be immutable and return the result of
the called function *and* a new context? But I dislike such theorical API,
since it would be complex to return the new context if the called function
raises an exception.

Victor
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Victor Stinner
Le 2 janv. 2018 18:57, "Guido van Rossum"  a écrit :

Oh, the "Specification" section in the PEP is too brief on several of these
subjects. It doesn't really specify what var.get() does if the value is not
set, nor does it even mention var.get() except in the code
examples for var.reset(). It's also subtle that ctx[var] returns the
default (if there is one). I suppose it will raise if there isn't one --
resulting in the somewhat surprising behavior where `var in ctx` may be
true but `ctx[var]` may raise. And what does it raise? (All these questions
are answered by the code, but they should be clearly stated in the PEP.)


A variable has or has no default value. Would it make sense to expose the
default value as a public read-only attribute (it would be equal to
_NO_DEFAULT or Token.MISSING if there is no default) and/or add a is_set()
method? is_set() returns true if the variable has a default value or if it
was set in the "current context".

Currently, a custom sentinel is needed to check if var.get(), ctx.get(var)
and ctx[var] would raise an exception or not. Example:

my_sentinel = object()
is_set = (var.get(default=my_sentinel) is not my_sentinel)
# no exception if is_set is true

ContextVar.get() is non obvious because the variable has an optinal
default, get() has an optional default parameter, and the variable can be
set or not in the current context.

Victor
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Victor Stinner
Why ContextVar.reset(token) does nothing at the second call with the same
token? What is the purpose of Token._used? I guess that there is an use
case to justify this behaviour.

reset() should have a result: true if the variable was restored to its
previous state, false if reset() did nothing because the token was already
used. And/Or Token should have a read-only "used" property.

Victor
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Victor Stinner
PEP:
"int PyContext_Enter(PyContext *) and int PyContext_Exit(PyContext *) allow
to set and restore the context for the current OS thread."

What is the difference between Enter and Exit? Why not having a single
Py_SetContext() function?

Victor
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Victor Stinner
What is the behaviour of ContextVar.reset(token) if the token was created
from a different variable? Raise an exception?

token = var1.set("value")
var2.reset(token)

The PEP states that Token.var only exists for debug or introspection.

Victor

Le 3 janv. 2018 00:51, "Victor Stinner"  a écrit :

Why ContextVar.reset(token) does nothing at the second call with the same
token? What is the purpose of Token._used? I guess that there is an use
case to justify this behaviour.

reset() should have a result: true if the variable was restored to its
previous state, false if reset() did nothing because the token was already
used. And/Or Token should have a read-only "used" property.

Victor
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Victor Stinner
Hum, it seems like the specification (API) part of the PEP is polluted by
its implementation. The PEP just require a few minor changes to better
describe the behaviour/API instead of insisting on the read only internal
thing which is specific to the proposed implementation which is just one
arbitrary implemention (designed for best performances).

IMHO the PEP shouldn't state that a context is read only. From my point of
view, it's mutable and it's the mapping holding variable values. There is a
current context which holds the current values. Context.run() switchs
temporarely the current context with another context. The fact that there
is no concrete context instance by default doesn't really matter in term of
API.

Victor

Le 3 janv. 2018 00:34, "Victor Stinner"  a écrit :

> > I would really like to invite more people to review this PEP! I expect
> I'll be accepting it in the next two weeks, but it needs to go through more
> rigorous review.
>
> I read again the PEP and I am still very confused by Context.run().
>
> The PEP states multiple times that a context is immutable:
>
> * "read-only mapping"
> * inherit from Mapping, not from MutableMapping
>
> But run() does modify the context (or please correct me if I completely 
> misunderstood
> the PEP! I had to read it 3 times to check if run() mutates or not the
> context).
>
> It would help if the ctx.run() example in the PEP would not only test
> var.get() but also test ctx.get(var). Or maybe show that the variable value
> is kept in a second function call, but the variable is "restored" between
> run() calls.
>
> The PEP tries hard to hide "context data", which is the only read only
> thing in the whole PEP, whereas it's a key concept to understand the
> implementation.
>
> I understood that:
>
> * _ContextData is immutable
> * ContextVar.set() creates a new _ContextData and sets it in the current
> Python thread state
> * When the called function completes, Context.run() sets its context data
> to the new context data from the Python thread state: so run() does modify
> the "immutable" context
>
>
> The distinction between the internal/hiden *immutable* context data and
> public/visible "mutable" (from my point of view) context is unclear to me
> in the PEP.
>
> The concept of "current context" is not defined in the PEP. In practice,
> there is no "current context", there is only a "current context data" in
> the current Python thread. There is no need for a concrete context instance
> to store variable variables values. It's also hard to understand that in
> the PEP.
>
>
> Why Context could not inherit from MutableMapping? (Allow ctx.set(var,
> value) and ctx [var] = value.) Is it just to keep the API small: changes
> should only be made using var.set()?
>
> Or maybe Context.run() should really be immutable and return the result of
> the called function *and* a new context? But I dislike such theorical API,
> since it would be complex to return the new context if the called function
> raises an exception.
>
> Victor
>
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Concerns about method overriding and subclassing with dataclasses

2018-01-02 Thread Stephen J. Turnbull
Chris Barker writes:

 > are we only talking about __repr__ here ???

I am, because I haven't thought about the other methods, except to
note I find it hard to imagine a use case *for me* that would require
any of them.  That sorta disqualifies me from comment. ;-)  I assumed
others were talking about all of the dataclass autogenerated methods,
though.

 > And the fact that you can optionally tell it not to in some particular case
 > keeps full flexibility.

AFAICS there is no question about that, just about *how* you indicate
that you do or don't want autobogotification.

 > Will you get the "right" __repr__ now if you derive a datacalss from a
 > dataclass? That would be a nice feature.

I hadn't thought about that: I wouldn't call it "nice", I'd say it's a
sine-qua-back-to-the-drawing-board.

___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Yury Selivanov
On Wed, Jan 3, 2018 at 2:36 AM Victor Stinner 
wrote:

> > I would really like to invite more people to review this PEP! I expect
> I'll be accepting it in the next two weeks, but it needs to go through more
> rigorous review.
>
> I read again the PEP and I am still very confused by Context.run().
>
> The PEP states multiple times that a context is immutable:
>
> * "read-only mapping"
> * inherit from Mapping, not from MutableMapping
>

> But run() does modify the context (or please correct me if I completely 
> misunderstood
> the PEP! I had to read it 3 times to check if run() mutates or not the
> context).
>
> It would help if the ctx.run() example in the PEP would not only test
> var.get() but also test ctx.get(var). Or maybe show that the variable value
> is kept in a second function call, but the variable is "restored" between
> run() calls.
>
> The PEP tries hard to hide "context data", which is the only read only
> thing in the whole PEP, whereas it's a key concept to understand the
> implementation.
>
> I understood that:
>
> * _ContextData is immutable
> * ContextVar.set() creates a new _ContextData and sets it in the current
> Python thread state
> * When the called function completes, Context.run() sets its context data
> to the new context data from the Python thread state: so run() does modify
> the "immutable" context
>

tuples in Python are immutable, but you can have a tuple with a dict as its
single element. The tuple is immutable, the dict is mutable.

At the C level we have APIs that can mutate a tuple though.

Now, tuple is not a direct analogy to Context, but there are some
parallels.  Context is a container like tuple, with some additional APIs on
top.


>
> The distinction between the internal/hiden *immutable* context data and
> public/visible "mutable" (from my point of view) context is unclear to me
> in the PEP.
>
> The concept of "current context" is not defined in the PEP. In practice,
> there is no "current context", there is only a "current context data" in
> the current Python thread. There is no need for a concrete context instance
> to store variable variables values. It's also hard to understand that in
> the PEP.
>
>
> Why Context could not inherit from MutableMapping? (Allow ctx.set(var,
> value) and ctx [var] = value.) Is it just to keep the API small: changes
> should only be made using var.set()?
>

Because that would be confusing to end users.

  ctx = copy_context()
  ctx[var] = something

What did we just do?  Did we modify the 'var' in the code that is currently
executing? No, you still need to call Context.run to see the new value for
var.

Another problem is that MutableMapping defines a __delitem__ method, which
i don't want the Context to implement.  Deleting variables like that is
incompatible with PEP 550, where it's ambiguous (due to the stacked nature
of contexts).

Now we don't want PEP 550 in 3.7, but I want to keep the door open for its
design, in case we want context to work with generators.


> Or maybe Context.run() should really be immutable and return the result of
> the called function *and* a new context? But I dislike such theorical API,
> since it would be complex to return the new context if the called function
> raises an exception.
>

It can't return a new context because the callable you're running can raise
an exception. In which case you'd lose modifications prior to the error.

ps i'm on vacation and don't always have an internet connection.

yury


> Victor
> ___
> Python-Dev mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com
>
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Yury Selivanov
On Wed, Jan 3, 2018 at 3:04 AM Victor Stinner 
wrote:

> What is the behaviour of ContextVar.reset(token) if the token was created
> from a different variable? Raise an exception?
>
> token = var1.set("value")
> var2.reset(token)
>
> The PEP states that Token.var only exists for debug or introspection.
>

It will raise an error. I'll specify this in the PEP.

Yury


> Victor
>
>
> Le 3 janv. 2018 00:51, "Victor Stinner"  a
> écrit :
>
> Why ContextVar.reset(token) does nothing at the second call with the same
> token? What is the purpose of Token._used? I guess that there is an use
> case to justify this behaviour.
>
> reset() should have a result: true if the variable was restored to its
> previous state, false if reset() did nothing because the token was already
> used. And/Or Token should have a read-only "used" property.
>
> Victor
>
>
> ___
> Python-Dev mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com
>
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Yury Selivanov
I don't want to expose a SetContext operation because of, again, potential
incompatibility with PEP 550, where generators expect to fully control
push/pop context operation.

Second, Context.run is 100% enough for *any* async framework to add support
for PEP 567. And because the PEP is focused just on async, I think that we
don't need anything more than 'run'.

Third, I have a suspicion that we focus too much on actual Context and
Context.run. These APIs are meant for asyncio/twisted/trio/etc maintainers,
not for an average Python user. An average person will likely not interact
with any of the PEP 567 machinery directly, wven when using PEP 567-enabled
libraries like numpy/decimal.

Yury

On Wed, Jan 3, 2018 at 2:56 AM Victor Stinner 
wrote:

> PEP:
> "int PyContext_Enter(PyContext *) and int PyContext_Exit(PyContext *)
> allow to set and restore the context for the current OS thread."
>
> What is the difference between Enter and Exit? Why not having a single
> Py_SetContext() function?
>
> Victor
> ___
> Python-Dev mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com
>
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Guido van Rossum
On Tue, Jan 2, 2018 at 5:30 PM, Victor Stinner 
wrote:

> Hum, it seems like the specification (API) part of the PEP is polluted by
> its implementation. The PEP just require a few minor changes to better
> describe the behaviour/API instead of insisting on the read only internal
> thing which is specific to the proposed implementation which is just one
> arbitrary implemention (designed for best performances).
>

Yeah, we need some more words. I still hope someone proposes some, but if
threats fail I will have to try to find time myself.


> IMHO the PEP shouldn't state that a context is read only. From my point of
> view, it's mutable and it's the mapping holding variable values. There is a
> current context which holds the current values. Context.run() switchs
> temporarely the current context with another context. The fact that there
> is no concrete context instance by default doesn't really matter in term of
> API.
>

I think the issue here is a bit different than Yury's response suggests --
it's more like how a variable containing an immutable value (e.g. a string)
can be modified, e.g.

x = 'a'
x += 'b'

In our case the *variable* is the current thread state (in particular the
slot therein that holds the context -- this slot can be modified by the C
API). The *value* is the Context object. It is a collections.Mapping (or
typing.Mapping) which does not have mutating methods. (The mutable type is
called MutableMapping.)

The *reason* for doing it this way is that Yury doesn't want Context to
implement __delitem__, since it would complicate the specification of
chained lookups by a future PEP, and chained lookups look to be the best
option to extend the Context machinery for generators. We're not doing that
in Python 3.7 (PEP 550 v2 and later did this but it was too complex) but we
might want to do in 3.8 or 3.9 once we are comfortable with PEP 567. (Or
not -- it's not clear to me that generators bite decimal users the way
tasks do. Coroutines always run on behalf of a task so they're not a
problem.)

--Guido



> Victor
>
> Le 3 janv. 2018 00:34, "Victor Stinner"  a
> écrit :
>
>> > I would really like to invite more people to review this PEP! I expect
>> I'll be accepting it in the next two weeks, but it needs to go through more
>> rigorous review.
>>
>> I read again the PEP and I am still very confused by Context.run().
>>
>> The PEP states multiple times that a context is immutable:
>>
>> * "read-only mapping"
>> * inherit from Mapping, not from MutableMapping
>>
>> But run() does modify the context (or please correct me if I completely 
>> misunderstood
>> the PEP! I had to read it 3 times to check if run() mutates or not the
>> context).
>>
>> It would help if the ctx.run() example in the PEP would not only test
>> var.get() but also test ctx.get(var). Or maybe show that the variable value
>> is kept in a second function call, but the variable is "restored" between
>> run() calls.
>>
>> The PEP tries hard to hide "context data", which is the only read only
>> thing in the whole PEP, whereas it's a key concept to understand the
>> implementation.
>>
>> I understood that:
>>
>> * _ContextData is immutable
>> * ContextVar.set() creates a new _ContextData and sets it in the current
>> Python thread state
>> * When the called function completes, Context.run() sets its context data
>> to the new context data from the Python thread state: so run() does modify
>> the "immutable" context
>>
>>
>> The distinction between the internal/hiden *immutable* context data and
>> public/visible "mutable" (from my point of view) context is unclear to me
>> in the PEP.
>>
>> The concept of "current context" is not defined in the PEP. In practice,
>> there is no "current context", there is only a "current context data" in
>> the current Python thread. There is no need for a concrete context instance
>> to store variable variables values. It's also hard to understand that in
>> the PEP.
>>
>>
>> Why Context could not inherit from MutableMapping? (Allow ctx.set(var,
>> value) and ctx [var] = value.) Is it just to keep the API small: changes
>> should only be made using var.set()?
>>
>> Or maybe Context.run() should really be immutable and return the result
>> of the called function *and* a new context? But I dislike such theorical API,
>> since it would be complex to return the new context if the called function
>> raises an exception.
>>
>> Victor
>>
>


-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Guido van Rossum
On Tue, Jan 2, 2018 at 4:45 PM, Victor Stinner 
wrote:

> Le 2 janv. 2018 18:57, "Guido van Rossum"  a écrit :
>
> Oh, the "Specification" section in the PEP is too brief on several of
> these subjects. It doesn't really specify what var.get() does if the value
> is not set, nor does it even mention var.get() except in the code
> examples for var.reset(). It's also subtle that ctx[var] returns the
> default (if there is one). I suppose it will raise if there isn't one --
> resulting in the somewhat surprising behavior where `var in ctx` may be
> true but `ctx[var]` may raise. And what does it raise? (All these questions
> are answered by the code, but they should be clearly stated in the PEP.)
>
>
> A variable has or has no default value. Would it make sense to expose the
> default value as a public read-only attribute (it would be equal to
> _NO_DEFAULT or Token.MISSING if there is no default) and/or add a is_set()
> method? is_set() returns true if the variable has a default value or if it
> was set in the "current context".
>
> Currently, a custom sentinel is needed to check if var.get(), ctx.get(var)
> and ctx[var] would raise an exception or not. Example:
>
> my_sentinel = object()
> is_set = (var.get(default=my_sentinel) is not my_sentinel)
> # no exception if is_set is true
>
> ContextVar.get() is non obvious because the variable has an optinal
> default, get() has an optional default parameter, and the variable can be
> set or not in the current context.
>

But is there a common use case? For var.get() I'd rather just pass the
default or catch the exception if the flow is different. Using ctx[var] is
rare (mostly for printing contexts, and perhaps for explaining var.get()).

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Guido van Rossum
On Tue, Jan 2, 2018 at 4:51 PM, Victor Stinner 
wrote:

> Why ContextVar.reset(token) does nothing at the second call with the same
> token? What is the purpose of Token._used? I guess that there is an use
> case to justify this behaviour.
>
> reset() should have a result: true if the variable was restored to its
> previous state, false if reset() did nothing because the token was already
> used. And/Or Token should have a read-only "used" property.
>

That depends again on the use case. The only real purpose for reset() is to
be able to write a context manager that sets and restores a context
variable (like in `with decimal.localcontext()`). Handling double resets is
about as useful as specifying what happens if __exit__ is called twice.

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 567 v2

2018-01-02 Thread Guido van Rossum
Do you see any average Python users on this thread? We are trying to pick
the PEP apart from the POV of having to use the complicated parts of the
API in a framework. Victor's questions are reasonable.

On Tue, Jan 2, 2018 at 10:13 PM, Yury Selivanov 
wrote:

> I don't want to expose a SetContext operation because of, again, potential
> incompatibility with PEP 550, where generators expect to fully control
> push/pop context operation.
>
> Second, Context.run is 100% enough for *any* async framework to add
> support for PEP 567. And because the PEP is focused just on async, I think
> that we don't need anything more than 'run'.
>
> Third, I have a suspicion that we focus too much on actual Context and
> Context.run. These APIs are meant for asyncio/twisted/trio/etc maintainers,
> not for an average Python user. An average person will likely not interact
> with any of the PEP 567 machinery directly, wven when using PEP 567-enabled
> libraries like numpy/decimal.
>
> Yury
>
> On Wed, Jan 3, 2018 at 2:56 AM Victor Stinner 
> wrote:
>
>> PEP:
>> "int PyContext_Enter(PyContext *) and int PyContext_Exit(PyContext *)
>> allow to set and restore the context for the current OS thread."
>>
>> What is the difference between Enter and Exit? Why not having a single
>> Py_SetContext() function?
>>
>> Victor
>> ___
>> Python-Dev mailing list
>> [email protected]
>> https://mail.python.org/mailman/listinfo/python-dev
>> Unsubscribe: https://mail.python.org/mailman/options/python-dev/
>> yselivanov.ml%40gmail.com
>>
>


-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com