Re: [Python-Dev] PEP 567 pre v3

2018-01-10 Thread Chris Jerdonek
On Wed, Jan 10, 2018 at 10:58 PM, Yury Selivanov
 wrote:
> On Thu, Jan 11, 2018 at 10:35 AM, Chris Jerdonek
>  wrote:
>> On Mon, Jan 8, 2018 at 11:02 PM, Nathaniel Smith  wrote:
>>> Right now, the set of valid states for a ContextVar are: it can hold
>>> any Python object, or it can be undefined. However, the only way it
>>> can be in the "undefined" state is in a new Context where it has never
>>> had a value; once it leaves the undefined state, it can never return
>>> to it.
>>
>> I know Yury responded to one aspect of this point later on in the
>> thread. However, in terms of describing the possible states without
>> reference to the internal Context mappings, IIUC, wouldn't it be more
>> accurate to view a ContextVar as a stack of values rather than just
>> the binary "holding an object or not"? This is to reflect the number
>> of times set() has been called (and so the number of times reset()
>> would need to be called to "empty" the ContextVar).
>
>
> But why do you want to think of ContextVar as a stack of values?  Or
> as something that is holding even one value?

I was primarily responding to Nathaniel's comment about how to
describe or talk about the state and not necessarily advocating that
view.

But to your question, like it or not, I think the API encourages this
way of thinking because the get() method is on the ContextVar itself,
and so it's the ContextVar which is doing the looking up rather than
just fulfilling the role of a key name. The API brings to mind other
containers and things holding values like dict.get(), queue.get(),
BytesIO.getvalue(), and container type's object.__getitem__(), etc. So
I think one will need to be prepared for many or most users having
this conception with the current API. (I think renaming to something
like ContextVar.lookup() or even ContextVar.value() would go a long
way towards dispelling that, but Guido said earlier in the thread that
he likes the shorter name.)

> Do Python variables hold/envelope objects they reference?  No, they
> don't.  They are simple names and are used to lookup objects in
> globals/locals dicts.  ContextVars are very similar!  They are *keys*
> in Context objects—that is it.

Python variables don't hold the objects. But the analogy also doesn't
quite match because variables also don't have get() methods. It's
Python which is doing the looking up in that case rather than the
variable itself. With ContextVars, it's serving both roles of name and
thing doing the looking up.

This is one reason why I suggested several days ago that I thought
something like contextvars.get(key) (where key is a ContextVar) would
be a less confusing API. That way the ContextVar / ContextKey(?) would
only be acting as a key and not also be responsible for doing the
lookup and knowing about what is containing it.

--Chris


>
> ContextVar.default is returned by ContextVar.get() when it cannot find
> the value for the context variable in the current Context object.  If
> ContextVar.default was not provided, a LookupError is raised.
>
> The reason why this is simpler for regular variables is because they
> have a dedicated syntax.  Instead of writing
>
> print(globals()['some_variable'])
>
> we simply write
>
> print(some_variable)
>
> Similarly for context variables, we could have written:
>
>print(copy_context()[var])
>
> But instead we use a ContextVar.get():
>
>print(var.get())
>
> If we had a syntax support for context variables, it would be like this:
>
>context var
>print(var)   # Lookups 'var' in the current context
>
> Although I very much doubt that we would *ever* want to have a
> dedicated syntax for context variables (they are very niche and are
> only needed in some very special cases), I hope that this line of
> thinking would help to clear the waters.
>
> Yury
___
Python-Dev mailing list
Python-Dev@python.org
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 pre v3

2018-01-10 Thread Yury Selivanov
On Thu, Jan 11, 2018 at 10:35 AM, Chris Jerdonek
 wrote:
> On Mon, Jan 8, 2018 at 11:02 PM, Nathaniel Smith  wrote:
>> Right now, the set of valid states for a ContextVar are: it can hold
>> any Python object, or it can be undefined. However, the only way it
>> can be in the "undefined" state is in a new Context where it has never
>> had a value; once it leaves the undefined state, it can never return
>> to it.
>
> I know Yury responded to one aspect of this point later on in the
> thread. However, in terms of describing the possible states without
> reference to the internal Context mappings, IIUC, wouldn't it be more
> accurate to view a ContextVar as a stack of values rather than just
> the binary "holding an object or not"? This is to reflect the number
> of times set() has been called (and so the number of times reset()
> would need to be called to "empty" the ContextVar).


But why do you want to think of ContextVar as a stack of values?  Or
as something that is holding even one value?

Do Python variables hold/envelope objects they reference?  No, they
don't.  They are simple names and are used to lookup objects in
globals/locals dicts.  ContextVars are very similar!  They are *keys*
in Context objects—that is it.

ContextVar.default is returned by ContextVar.get() when it cannot find
the value for the context variable in the current Context object.  If
ContextVar.default was not provided, a LookupError is raised.

The reason why this is simpler for regular variables is because they
have a dedicated syntax.  Instead of writing

print(globals()['some_variable'])

we simply write

print(some_variable)

Similarly for context variables, we could have written:

   print(copy_context()[var])

But instead we use a ContextVar.get():

   print(var.get())

If we had a syntax support for context variables, it would be like this:

   context var
   print(var)   # Lookups 'var' in the current context

Although I very much doubt that we would *ever* want to have a
dedicated syntax for context variables (they are very niche and are
only needed in some very special cases), I hope that this line of
thinking would help to clear the waters.

Yury
___
Python-Dev mailing list
Python-Dev@python.org
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 pre v3

2018-01-10 Thread Yury Selivanov
On Thu, Jan 11, 2018 at 10:39 AM, Ethan Furman  wrote:
> On 01/10/2018 10:23 PM, Yury Selivanov wrote:
[..]
>> Therefore I'm still in favour of keeping the current PEP 567
>> behaviour.
>
>
> To be clear:  We'll now be able to specify a default when we create the
> variable, but we can also leave it out so a LookupError can be raised later?

Correct.

Yury
___
Python-Dev mailing list
Python-Dev@python.org
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 pre v3

2018-01-10 Thread Ethan Furman

On 01/10/2018 10:23 PM, Yury Selivanov wrote:

On Thu, Jan 11, 2018 at 4:44 AM, Nathaniel Smith wrote:



It may have gotten lost in that email, but my actual favorite approach
is that we make the signatures:

ContextVar(name, *, initial_value)  # or even (*, name, initial_value)
ContextVar.get()
ContextVar.set(value)

so that when you create a ContextVar you always state the initial
value, whatever makes sense in a particular case. (Obviously None will
be a very popular choice, but this way it won't be implicit, and
no-one will be surprised to see it returned from get().)


Alright, you've shown that most of the time when we use
threading.local in the standard library we subclass it in order to
provide a default value (and avoid AttributeError being thrown).  This
is a solid argument in favour of keeping the 'default' parameter for
the ContextVar constructor.  Let's keep it.


[...]


I think that when you have an int stored in a context variable it
would usually make sense to give it a 0 default (or some other
number). However, for a complex object (like current request object)
there is *no* sensible default value sometimes.  Forcing the user to
set it to None feels like a badly designed API that forces the user to
work around it.

Therefore I'm still in favour of keeping the current PEP 567
behaviour.


To be clear:  We'll now be able to specify a default when we create the variable, but we can also leave it out so a 
LookupError can be raised later?


--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
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 pre v3

2018-01-10 Thread Chris Jerdonek
On Mon, Jan 8, 2018 at 11:02 PM, Nathaniel Smith  wrote:
> Right now, the set of valid states for a ContextVar are: it can hold
> any Python object, or it can be undefined. However, the only way it
> can be in the "undefined" state is in a new Context where it has never
> had a value; once it leaves the undefined state, it can never return
> to it.

I know Yury responded to one aspect of this point later on in the
thread. However, in terms of describing the possible states without
reference to the internal Context mappings, IIUC, wouldn't it be more
accurate to view a ContextVar as a stack of values rather than just
the binary "holding an object or not"? This is to reflect the number
of times set() has been called (and so the number of times reset()
would need to be called to "empty" the ContextVar).

--Chris



>
> This makes me itch. It's very weird to have a mutable variable with a
> valid state that you can't reach by mutating it. I see two
> self-consistent ways to make me stop itching: (a) double-down on
> undefined as being part of ContextVar's domain, or (b) reduce the
> domain so that undefined is never a valid state.
>
> # Option 1
>
> In the first approach, we conceptualize ContextVar as being a
> container that either holds a value or is empty (and then there's one
> of these containers for each context). We also want to be able to
> define an initial value that the container takes on when a new context
> materializes, because that's really convenient. And then after that we
> provide ways to get the value (if present), or control the value
> (either set it to a particular value or unset it). So something like:
>
> var1 = ContextVar("var1")  # no initial value
> var2 = ContextVar("var2", initial_value="hello")
>
> with assert_raises(SomeError):
> var1.get()
> # get's default lets us give a different outcome in cases where it
> would otherwise raise
> assert var1.get(None) is None
> assert var2.get() == "hello"
> # If get() doesn't raise, then the argument is ignored
> assert var2.get(None) == "hello"
>
> # We can set to arbitrary values
> for var in [var1, var2]:
> var.set("new value")
> assert var.get() == "new value"
>
> # We can unset again, so get() will raise
> for var in [var1, var2]:
> var.unset()
> with assert_raises(SomeError):
> var.get()
> assert var.get(None) is None
>
> To fulfill all that, we need an implementation like:
>
> MISSING = make_sentinel()
>
> class ContextVar:
> def __init__(self, name, *, initial_value=MISSING):
> self.name = name
> self.initial_value = initial_value
>
> def set(self, value):
> if value is MISSING: raise TypeError
> current_context()._dict[self] = value
> # Token handling elided because it's orthogonal to this issue
> return Token(...)
>
> def unset(self):
> current_context()._dict[self] = MISSING
> # Token handling elided because it's orthogonal to this issue
> return Token(...)
>
> def get(self, default=_NOT_GIVEN):
> value = current_context().get(self, self.initial_value)
> if value is MISSING:
> if default is _NOT_GIVEN:
> raise ...
> else:
> return default
> else:
> return value
>
> Note that the implementation here is somewhat tricky and non-obvious.
> In particular, to preserve the illusion of a simple container with an
> optional initial value, we have to encode a logically undefined
> ContextVar as one that has Context[var] set to MISSING, and a missing
> entry in Context encodes the presence of the inital value. If we
> defined unset() as 'del current_context._dict[self]', then we'd have:
>
> var2.unset()
> assert var2.get() is None
>
> which would be very surprising to users who just want to think about
> ContextVars and ignore all that stuff about Contexts. This, in turn,
> means that we need to expose the MISSING sentinel in general, because
> anyone introspecting Context objects directly needs to know how to
> recognize this magic value to interpret things correctly.
>
> AFAICT this is the minimum complexity required to get a complete and
> internally-consistent set of operations for a ContextVar that's
> conceptualized as being a container that either holds an arbitrary
> value or is empty.
>
> # Option 2
>
> The other complete and coherent conceptualization I see is to say that
> a ContextVar always holds a value. If we eliminate the "unset" state
> entirely, then there's no "missing unset method" -- there just isn't
> any concept of an unset value in the first place, so there's nothing
> to miss. This idea shows up in lots of types in Python, actually --
> e.g. for any exception object, obj.__context__ is always defined. Its
> value might be None, but it has a value. In this approach,
> ContextVar's are similar.
>
> To fulfill all that, we need an implementation like:
>
> class ContextVar:
> # Or maybe it'd be better to ma

Re: [Python-Dev] PEP 567 pre v3

2018-01-10 Thread Yury Selivanov
On Thu, Jan 11, 2018 at 4:44 AM, Nathaniel Smith  wrote:
[..]
> It may have gotten lost in that email, but my actual favorite approach
> is that we make the signatures:
>
> ContextVar(name, *, initial_value)  # or even (*, name, initial_value)
> ContextVar.get()
> ContextVar.set(value)
>
> so that when you create a ContextVar you always state the initial
> value, whatever makes sense in a particular case. (Obviously None will
> be a very popular choice, but this way it won't be implicit, and
> no-one will be surprised to see it returned from get().)

Alright, you've shown that most of the time when we use
threading.local in the standard library we subclass it in order to
provide a default value (and avoid AttributeError being thrown).  This
is a solid argument in favour of keeping the 'default' parameter for
the ContextVar constructor.  Let's keep it.

However I still don't like the idea of making defaults mandatory.  I
have at least one exemplary use case (I can come up with more of such
examples, btw) which shows that it's not always desired to have a None
default: getting the current request object in a web application.
With the current PEP 567 semantics:

request_var: ContextVar[Request] = ContextVar('current_request')

and later:

request : Request = request_var.get()

'request_var.get()' will throw a LookupError, which will indicate that
something went wrong in the framework layer.  The user should never
see this error, and they can just rely on the fact that the current
request is always available (cannot be None).

With mandatory defaults, the type of 'request' variable will be
'Optional[Request]', and the user will be forced to add an 'if'
statement to guard against None values.  Otherwise the user risks
having occasional AttributeErrors that don't really explain what
actually happened.  I would prefer them to see a LookupError('cannot
lookup current_request context variable') instead.

I think that when you have an int stored in a context variable it
would usually make sense to give it a 0 default (or some other
number). However, for a complex object (like current request object)
there is *no* sensible default value sometimes.  Forcing the user to
set it to None feels like a badly designed API that forces the user to
work around it.

Therefore I'm still in favour of keeping the current PEP 567
behaviour.  It feels very consistent with how variable lookups and
threading.local objects work in Python now.

Yury
___
Python-Dev mailing list
Python-Dev@python.org
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 pre v3

2018-01-10 Thread Nick Coghlan
On 11 January 2018 at 10:44, Nathaniel Smith  wrote:
> It may have gotten lost in that email, but my actual favorite approach
> is that we make the signatures:
>
> ContextVar(name, *, initial_value)  # or even (*, name, initial_value)
> ContextVar.get()
> ContextVar.set(value)
>
> so that when you create a ContextVar you always state the initial
> value, whatever makes sense in a particular case. (Obviously None will
> be a very popular choice, but this way it won't be implicit, and
> no-one will be surprised to see it returned from get().)

I also like this idea, and I think it aligns better with "dict.get"
than it may first appear: the trick is that in this simplified API
"ContextVar.get()" would be akin to
"get_thread_state().current_context.get(cv, cv.initial_value)" (and
PEP 568 wouldn't really change that).

So both the key and the default value are specified at ContextVar
initialisation time, and if you want to supply a non-standard default,
then you need to break the ContextVar abstraction, and access
"contextvars.copy_context().get(cv, custom_default)" instead.

If we later decide that we do want to support raising an exception for
unitialised access after all, then we could introduce a "missing"
callback to the ContextVar constructor that would be akin to
defaultdict's "default_factory" callback (with the requirement
becoming that you have to specify either an initial_value, or a
missing callback, but not both).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-Dev mailing list
Python-Dev@python.org
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 pre v3

2018-01-10 Thread Nathaniel Smith
On Tue, Jan 9, 2018 at 3:41 AM, Yury Selivanov  wrote:
> On Tue, Jan 9, 2018 at 11:02 AM, Nathaniel Smith  wrote:
>> Right now, the set of valid states for a ContextVar are: it can hold
>> any Python object, or it can be undefined. However, the only way it
>> can be in the "undefined" state is in a new Context where it has never
>> had a value; once it leaves the undefined state, it can never return
>> to it.
>
> Is "undefined" a state when a context variable doesn't have a default
> and isn't yet set?  If so, why can't it be returned back to the
> "undefined" state?  That's why we have the 'reset' method:

Sorry, yes, you can return to the "undefined" state if you have a
valid token that hasn't been used yet. But my point is that it's weird
to have a variable that needs so many words to describe which kinds of
state transitions are possible.

> I don't like how context variables are defined in Option 1 and Option
> 2.  I view ContextVars as keys in some global context mapping--akin to
> Python variables.

This is one totally reasonable option but, I mean... it's software,
there are lots of options for how to view things that we could
potentially make true, and we get to pick the one that works best :-).
And I think it's easier to explain to users how ContextVar works if we
can do it without talking about Context mappings etc.

Thread-local storage is also implemented using some per-thread maps
and various clever tricks, but I don't think I've ever seen
documentation that described it that way.

> In any case, at this point I think that the best option is to simply
> drop the "default" parameter from the ContextVar constructor.  This
> would leave us with only one default in ContextVar.get() method:
>
> c.get()   # Will raise a LookupError if 'c' is not set
> c.get('python')  # Will return 'python' if 'c' is not set
>
> I also now see how having two different 'default' values: one defined
> when a ContextVar is created, and one can be passed to
> ContextVar.get() is confusing.

But the constructor default is way more important for usability than
any of the other features we're talking about! Every time I use
threading.local, I get annoyed that there isn't a simpler way to
specify a default value. OTOH I've never found a case where I actually
wanted undefined values.

To find out whether my experience is typical, I did a quick grep of
the stdlib, and found 5 thread local variables:

- asyncio.events._BaseEventLoopPolicy._local.{_loop, _set_called}:
These two use the 'subclass threading.local' trick to make it seem
like these are initialized to None.

- asyncio.events._running_loop: This uses the subclass trick to to
make it seem like it's initialized to (None, None).

- multiprocessing.context._tls.spawning_popen: Here the code defines
two accessors (get_spawning_popen, set_spawning_popen) that make it
seem like it's initialized to None. Of course you could do this with
ContextVar's too, but if ContextVar had native support for specifying
an initial value then they'd be unnecessary, because
spawning_popen.get()/set() would already do the right thing.

- _pydecimal.local.__decimal_context__: This is a little trickier. It
has a default value, but it's mutable, so access is hidden behind two
accessors (getcontext, setcontext) and it's initialized on first
access. Currently this is done with a try: except:, but if thread
locals had the ability to set the default to None, then using that
would make the implementation shorter and faster (exceptions are
expensive).

So that's 5 out of 5 cases where the code would get simpler if
thread-locals had the ability to specify a default initial value, 0
out of 5 cases where anyone would miss support for undefined values or
wants to be able to control the default get() value on a call-by-call
basis.

The argument for supporting undefined values in ContextVar is mostly
by analogy with regular Python variables. I like analogies, but I
don't think we should sacrifice actual use cases to preserve the
analogy.

> But I'd be -1 on making all ContextVars have a None default
> (effectively have a "ContextVar.get(default=None)" signature. This
> would be a very loose semantics in my opinion.

It may have gotten lost in that email, but my actual favorite approach
is that we make the signatures:

ContextVar(name, *, initial_value)  # or even (*, name, initial_value)
ContextVar.get()
ContextVar.set(value)

so that when you create a ContextVar you always state the initial
value, whatever makes sense in a particular case. (Obviously None will
be a very popular choice, but this way it won't be implicit, and
no-one will be surprised to see it returned from get().)

-n

-- 
Nathaniel J. Smith -- https://vorpus.org
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Bug report in audioop module.

2018-01-10 Thread MRAB

On 2018-01-10 20:37, Moses Egypt wrote:
I was told to post this here when I asked what to do on the python 
reddit. This is the issue:

https://bugs.python.org/issue32004

It has received no response since I posted it two months ago, so I 
figured I didn't fill something out correctly to get it put on someone's 
tracker. This is my first bug report, so please let me know if there is 
anything I need to do get it appointed to the correct person next time. 
Thanks.


This is open source; nothing gets done unless someone chooses to do it, 
usually because it "scratches their itch" or they have a problem and 
no-one else is interested in doing it.

If you don't get any response, you could always try fixing it yourself.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Bug report in audioop module.

2018-01-10 Thread Nick Coghlan
On 11 January 2018 at 06:37, Moses Egypt  wrote:
> I was told to post this here when I asked what to do on the python reddit.
> This is the issue:
> https://bugs.python.org/issue32004

Thank you for taking the time to file that!

> It has received no response since I posted it two months ago, so I figured I
> didn't fill something out correctly to get it put on someone's tracker. This
> is my first bug report, so please let me know if there is anything I need to
> do get it appointed to the correct person next time. Thanks.

You've actually done everything right - it's just hit or miss as to
whether or not issues will attract a core developer's attention.
(Unfortunately there aren't currently any jobs in the world that have
"Help limit the growth of the CPython issue count in general" as a
requirement, so there aren't any kind of consistent response time
assurance for issues or pull requests).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-Dev mailing list
Python-Dev@python.org
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-10 Thread Nathaniel Smith
On Tue, Jan 9, 2018 at 2:59 AM, Yury Selivanov  wrote:
>
>
>> On Jan 9, 2018, at 11:18 AM, Nathaniel Smith  wrote:
>> The approach I took in PEP 568 is even simpler, I think. The PEP is a
>> few pages long because I wanted to be exhaustive to make sure we
>> weren't missing any details, but the tl;dr is: The ChainMap lives
>> entirely inside the threadstate, so there's no need to create a LC/EC
>> distinction -- users just see Contexts, or there's the one stack
>> introspection API, get_context_stack(), which returns a List[Context].
>> Instead of messing with new_child, copy_context is just
>> Context(dict(chain_map)) -- i.e., it creates a flattened copy of the
>> current mapping. (If we used new_child, then we'd have to have a way
>> to return a ChainMap, reintroducing the LC/EC mess.
>
> This sounds reasonable. Although keep in mind that merging hamt is still an 
> expensive operation, so flattening shouldn't always be performed (this is 
> covered in 550).

Right, the PEP mostly focuses on the semantics rather than the
implementation and this is an implementation detail (the user can't
tell whether a Context internally holds a stack of HAMTs or just one).
But there is a note that we might choose to perform the actual
flattening lazily if it turns out to be worthwhile.

> I also wouldn't call LC/EC a "mess". Your pep just names things differently, 
> but otherwise is entirely built on concepts and ideas introduced in pep 550.

Sorry for phrasing it like that -- I just meant that at the API level,
the LC/EC split caused a lot of confusion (and apparently this was
it's "nail in the coffin"!). In the PEP 567/568 version, the
underlying concepts are the same, but the API ends up being simpler.

-n

-- 
Nathaniel J. Smith -- https://vorpus.org
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Bug report in audioop module.

2018-01-10 Thread Moses Egypt
I was told to post this here when I asked what to do on the python reddit.
This is the issue:
https://bugs.python.org/issue32004

It has received no response since I posted it two months ago, so I figured
I didn't fill something out correctly to get it put on someone's tracker.
This is my first bug report, so please let me know if there is anything I
need to do get it appointed to the correct person next time. Thanks.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Thoughts on "contexts". PEPs 550, 555, 567, 568

2018-01-10 Thread Guido van Rossum
I'm sorry, Koos, but based on your past contributions I am not interested
in discussing this topic with you.

On Wed, Jan 10, 2018 at 8:58 AM, Koos Zevenhoven  wrote:

> The status of PEP 555 is just a side track. Here, I took a step back
> compared to what went into PEP 555.
>
> —Koos
>
>
> On Wed, Jan 10, 2018 at 6:21 PM, Guido van Rossum 
> wrote:
>
>> The current status of PEP 555 is "Withdrawn". I have no interest in
>> considering it any more, so if you'd rather see a decision from me I'll be
>> happy to change it to "Rejected".
>>
>> On Tue, Jan 9, 2018 at 10:29 PM, Koos Zevenhoven 
>> wrote:
>>
>>> On Jan 10, 2018 07:17, "Yury Selivanov"  wrote:
>>>
>>> Wasn't PEP 555 rejected by Guido? What's the point of this post?
>>>
>>>
>>> I sure hope there is a point. I don't think mentioning PEP 555 in the
>>> discussions should hurt.
>>>
>>> A typo in my post btw: should be "PEP 567 (+568 ?)" in the second
>>> paragraph of course.
>>>
>>> -- Koos (mobile)
>>>
>>>
>>> Yury
>>>
>>> On Wed, Jan 10, 2018 at 4:08 AM Koos Zevenhoven 
>>> wrote:
>>>
 Hi all,

 I feel like I should write some thoughts regarding the "context"
 discussion, related to the various PEPs.

 I like PEP 567 (+ 567 ?) better than PEP 550. However, besides
 providing cvar.set(), I'm not really sure about the gain compared to PEP
 555 (which could easily have e.g. a dict-like interface to the context).
 I'm still not a big fan of "get"/"set" here, but the idea was indeed to
 provide those on top of a PEP 555 type thing too.

 "Tokens" in PEP 567, seems to resemble assignment context managers in
 PEP 555. However, they feel a bit messy to me, because they make it look
 like one could just set a variable and then revert the change at any point
 in time after that.

 PEP 555 is in fact a simplification of my previous sketch that had a
 .set(..) in it, but was somewhat different from PEP 550. The idea was to
 always explicitly define the scope of contextvar values. A context manager
 / with statement determined the scope of .set(..) operations inside the
 with statement:

 # Version A:
 cvar.set(1)
 with context_scope():
 cvar.set(2)

 assert cvar.get() == 2

 assert cvar.get() == 1

 Then I added the ability to define scopes for different variables
 separately:

 # Version B
 cvar1.set(1)
 cvar2.set(2)
 with context_scope(cvar1):
 cvar1.set(11)
 cvar2.set(22)

 assert cvar1.get() == 1
 assert cvar2.get() == 22


 However, in practice, most libraries would wrap __enter__, set and
 __exit__ into another context manager. So maybe one might want to allow
 something like

 # Version C:
 assert cvar.get() == something
 with context_scope(cvar, 2):
 assert cvar.get() == 2

 assert cvar.get() == something


 But this then led to combining "__enter__" and ".set(..)" into
 Assignment.__enter__ -- and "__exit__" into Assignment.__exit__ like this:

 # PEP 555 draft version:
 assert cvar.value == something
 with cvar.assign(1):
 assert cvar.value == 1

 assert cvar.value == something


 Anyway, given the schedule, I'm not really sure about the best thing to
 do here. In principle, something like in versions A, B and C above could be
 done (I hope the proposal was roughly self-explanatory based on earlier
 discussions). However, at this point, I'd probably need a lot of help to
 make that happen for 3.7.

 -- Koos

 ___
 Python-Dev mailing list
 Python-Dev@python.org
 https://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe: https://mail.python.org/mailma
 n/options/python-dev/yselivanov.ml%40gmail.com

>>>
>>>
>>> ___
>>> Python-Dev mailing list
>>> Python-Dev@python.org
>>> https://mail.python.org/mailman/listinfo/python-dev
>>> Unsubscribe: https://mail.python.org/mailma
>>> n/options/python-dev/guido%40python.org
>>>
>>>
>>
>>
>> --
>> --Guido van Rossum (python.org/~guido)
>>
>
>
>
> --
> + Koos Zevenhoven + http://twitter.com/k7hoven +
>



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


Re: [Python-Dev] Thoughts on "contexts". PEPs 550, 555, 567, 568

2018-01-10 Thread Koos Zevenhoven
The status of PEP 555 is just a side track. Here, I took a step back
compared to what went into PEP 555.

—Koos


On Wed, Jan 10, 2018 at 6:21 PM, Guido van Rossum  wrote:

> The current status of PEP 555 is "Withdrawn". I have no interest in
> considering it any more, so if you'd rather see a decision from me I'll be
> happy to change it to "Rejected".
>
> On Tue, Jan 9, 2018 at 10:29 PM, Koos Zevenhoven 
> wrote:
>
>> On Jan 10, 2018 07:17, "Yury Selivanov"  wrote:
>>
>> Wasn't PEP 555 rejected by Guido? What's the point of this post?
>>
>>
>> I sure hope there is a point. I don't think mentioning PEP 555 in the
>> discussions should hurt.
>>
>> A typo in my post btw: should be "PEP 567 (+568 ?)" in the second
>> paragraph of course.
>>
>> -- Koos (mobile)
>>
>>
>> Yury
>>
>> On Wed, Jan 10, 2018 at 4:08 AM Koos Zevenhoven 
>> wrote:
>>
>>> Hi all,
>>>
>>> I feel like I should write some thoughts regarding the "context"
>>> discussion, related to the various PEPs.
>>>
>>> I like PEP 567 (+ 567 ?) better than PEP 550. However, besides providing
>>> cvar.set(), I'm not really sure about the gain compared to PEP 555 (which
>>> could easily have e.g. a dict-like interface to the context). I'm still not
>>> a big fan of "get"/"set" here, but the idea was indeed to provide those on
>>> top of a PEP 555 type thing too.
>>>
>>> "Tokens" in PEP 567, seems to resemble assignment context managers in
>>> PEP 555. However, they feel a bit messy to me, because they make it look
>>> like one could just set a variable and then revert the change at any point
>>> in time after that.
>>>
>>> PEP 555 is in fact a simplification of my previous sketch that had a
>>> .set(..) in it, but was somewhat different from PEP 550. The idea was to
>>> always explicitly define the scope of contextvar values. A context manager
>>> / with statement determined the scope of .set(..) operations inside the
>>> with statement:
>>>
>>> # Version A:
>>> cvar.set(1)
>>> with context_scope():
>>> cvar.set(2)
>>>
>>> assert cvar.get() == 2
>>>
>>> assert cvar.get() == 1
>>>
>>> Then I added the ability to define scopes for different variables
>>> separately:
>>>
>>> # Version B
>>> cvar1.set(1)
>>> cvar2.set(2)
>>> with context_scope(cvar1):
>>> cvar1.set(11)
>>> cvar2.set(22)
>>>
>>> assert cvar1.get() == 1
>>> assert cvar2.get() == 22
>>>
>>>
>>> However, in practice, most libraries would wrap __enter__, set and
>>> __exit__ into another context manager. So maybe one might want to allow
>>> something like
>>>
>>> # Version C:
>>> assert cvar.get() == something
>>> with context_scope(cvar, 2):
>>> assert cvar.get() == 2
>>>
>>> assert cvar.get() == something
>>>
>>>
>>> But this then led to combining "__enter__" and ".set(..)" into
>>> Assignment.__enter__ -- and "__exit__" into Assignment.__exit__ like this:
>>>
>>> # PEP 555 draft version:
>>> assert cvar.value == something
>>> with cvar.assign(1):
>>> assert cvar.value == 1
>>>
>>> assert cvar.value == something
>>>
>>>
>>> Anyway, given the schedule, I'm not really sure about the best thing to
>>> do here. In principle, something like in versions A, B and C above could be
>>> done (I hope the proposal was roughly self-explanatory based on earlier
>>> discussions). However, at this point, I'd probably need a lot of help to
>>> make that happen for 3.7.
>>>
>>> -- Koos
>>>
>>> ___
>>> Python-Dev mailing list
>>> Python-Dev@python.org
>>> https://mail.python.org/mailman/listinfo/python-dev
>>> Unsubscribe: https://mail.python.org/mailma
>>> n/options/python-dev/yselivanov.ml%40gmail.com
>>>
>>
>>
>> ___
>> Python-Dev mailing list
>> Python-Dev@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)
>



-- 
+ Koos Zevenhoven + http://twitter.com/k7hoven +
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Thoughts on "contexts". PEPs 550, 555, 567, 568

2018-01-10 Thread Guido van Rossum
The current status of PEP 555 is "Withdrawn". I have no interest in
considering it any more, so if you'd rather see a decision from me I'll be
happy to change it to "Rejected".

On Tue, Jan 9, 2018 at 10:29 PM, Koos Zevenhoven  wrote:

> On Jan 10, 2018 07:17, "Yury Selivanov"  wrote:
>
> Wasn't PEP 555 rejected by Guido? What's the point of this post?
>
>
> I sure hope there is a point. I don't think mentioning PEP 555 in the
> discussions should hurt.
>
> A typo in my post btw: should be "PEP 567 (+568 ?)" in the second
> paragraph of course.
>
> -- Koos (mobile)
>
>
> Yury
>
> On Wed, Jan 10, 2018 at 4:08 AM Koos Zevenhoven  wrote:
>
>> Hi all,
>>
>> I feel like I should write some thoughts regarding the "context"
>> discussion, related to the various PEPs.
>>
>> I like PEP 567 (+ 567 ?) better than PEP 550. However, besides providing
>> cvar.set(), I'm not really sure about the gain compared to PEP 555 (which
>> could easily have e.g. a dict-like interface to the context). I'm still not
>> a big fan of "get"/"set" here, but the idea was indeed to provide those on
>> top of a PEP 555 type thing too.
>>
>> "Tokens" in PEP 567, seems to resemble assignment context managers in PEP
>> 555. However, they feel a bit messy to me, because they make it look like
>> one could just set a variable and then revert the change at any point in
>> time after that.
>>
>> PEP 555 is in fact a simplification of my previous sketch that had a
>> .set(..) in it, but was somewhat different from PEP 550. The idea was to
>> always explicitly define the scope of contextvar values. A context manager
>> / with statement determined the scope of .set(..) operations inside the
>> with statement:
>>
>> # Version A:
>> cvar.set(1)
>> with context_scope():
>> cvar.set(2)
>>
>> assert cvar.get() == 2
>>
>> assert cvar.get() == 1
>>
>> Then I added the ability to define scopes for different variables
>> separately:
>>
>> # Version B
>> cvar1.set(1)
>> cvar2.set(2)
>> with context_scope(cvar1):
>> cvar1.set(11)
>> cvar2.set(22)
>>
>> assert cvar1.get() == 1
>> assert cvar2.get() == 22
>>
>>
>> However, in practice, most libraries would wrap __enter__, set and
>> __exit__ into another context manager. So maybe one might want to allow
>> something like
>>
>> # Version C:
>> assert cvar.get() == something
>> with context_scope(cvar, 2):
>> assert cvar.get() == 2
>>
>> assert cvar.get() == something
>>
>>
>> But this then led to combining "__enter__" and ".set(..)" into
>> Assignment.__enter__ -- and "__exit__" into Assignment.__exit__ like this:
>>
>> # PEP 555 draft version:
>> assert cvar.value == something
>> with cvar.assign(1):
>> assert cvar.value == 1
>>
>> assert cvar.value == something
>>
>>
>> Anyway, given the schedule, I'm not really sure about the best thing to
>> do here. In principle, something like in versions A, B and C above could be
>> done (I hope the proposal was roughly self-explanatory based on earlier
>> discussions). However, at this point, I'd probably need a lot of help to
>> make that happen for 3.7.
>>
>> -- Koos
>>
>> ___
>> Python-Dev mailing list
>> Python-Dev@python.org
>> https://mail.python.org/mailman/listinfo/python-dev
>> Unsubscribe: https://mail.python.org/mailman/options/python-dev/yselivano
>> v.ml%40gmail.com
>>
>
>
> ___
> Python-Dev mailing list
> Python-Dev@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)
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Best Python API for exposing posix_spawn

2018-01-10 Thread Pablo Galindo Salgado
I think I really like Antoine's suggestion so I'm going to finish
implementing it that way. I think this keeps the API simple, does not bring
in the os module new dependencies, keeps the C implementation clean and is
consistent with the rest of the posix module. I will post an update when is
ready.

Thank you everyone for sharing your view and advice!
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com