Re: [Python-Dev] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Nick Coghlan
On 24 August 2017 at 23:52, Barry Warsaw  wrote:
> Guido van Rossum wrote:
>> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
>>
>> I worry that that's going to lead more people astray thinking this has
>> something to do with contextlib, which it really doesn't (it's much more
>> closely related to threading.local()).
>
> This is my problem with using "Context" for this PEP.  Although I can't
> keep up with all names being thrown around, it seems to me that in
> Python we already have a well-established meaning for "contexts" --
> context managers, and the protocols they implement as they participate
> in `with` statements.  We have contextlib which reinforces this.  What's
> being proposed in PEP 550 is so far removed from this concept that I
> think it's just going to cause confusion (well, it does in me anyway!).

While I understand the concern, I think context locals and contextlib
are more closely related than folks realise, as one of the main
problems that the PEP is aiming to solve is that with statements (and
hence context managers) *do not work as expected* when their body
includes "yield", "yield from" or "await" .

The reason they don't work reliably is because in the absence of frame
hacks, context managers are currently limited to manipulating process
global and thread local state - there's no current notion of context
local storage that interacts nicely with the frame suspension
keywords. And hence in the absence of any support for context local
state, any state changes made by context managers tend to remain in
effect *even if the frame that entered the context manager gets
suspended*.

Context local state makes it possible to solve that problem, as it
means that encountering one of the frame suspension keywords in the
body of a with statement will implicitly revert all changes made to
context local variables until such time as that particular frame is
resumed, and you have to explicitly opt-in on a per-instance basis to
instead allow those state changes to affect the calling context that's
suspending & resuming the frame.

That said, I can also see Guido's point that the proposed new APIs
have a very different flavour to the existing APIs in contextlib, so
it doesn't necessarily make sense to use that module directly.

Building on the "context locals" naming scheme I've been discussing
elsewhere, one possible name for a dedicated module would be
"contextlocals" giving:

# Read/write access to individual context locals
* context_var = contextlocals.new_context_local(name: str='...')

# Context local storage manipulation
* context = contextlocals.new_context_local_state()
* contextlocals.run_with_context_locals(context: ContextLocalState,
func, *args, **kwargs).
* __context_locals__ attribute on generators and coroutines

# Overall execution context manipulation
* current_ec = contextlocals.get_execution_context()
* new_ec = contextlocals.new_execution_context()
* contextlocals.run_with_execution_context(ec: ExecutionContext, func,
*args, **kwargs).

The remaining connection with "contextlib" would be that
@contextlib.contextmanager (and its async counterpart) would
implicitly clear the __context_locals__ attribute on the underlying
generator instance so that context local state changes made there will
affect the context where the context manager is actually being used.

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 550 v3 naming

2017-08-24 Thread Guido van Rossum
I think we should let the naming issue go for now, while Yury et al. are
rewriting the PEP. We'll revisit it after we're more comfortable with the
semantics.

On Thu, Aug 24, 2017 at 9:55 PM, Nick Coghlan  wrote:

> On 25 August 2017 at 01:00, Guido van Rossum  wrote:
> > It shouldn't be called a namespace unless the dominant access is via
> > attributes.
>
> That makes sense.
>
> Since the main purpose of that part of the Python API is to offer an
> opaque handle to where the context locals store their values,
> something semantically neutral like "State" may work:
>
> - ContextLocal: read/write API
> - ContextLocalState: where ContextLocal instances actually store things
> - ExecutionContext: nested stack of context local states
>
> The attribute on generators and coroutines could then be called
> "__context_locals__", and that would either be None (indicating that
> any context local references will just use the already active context
> local storage), or else it would be set to a ContextLocalState
> instance (indicate that starting & stopping the operation will push &
> pop the given context local state).
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
>



-- 
--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] PEP 550 v3 naming

2017-08-24 Thread Nick Coghlan
On 25 August 2017 at 01:00, Guido van Rossum  wrote:
> It shouldn't be called a namespace unless the dominant access is via
> attributes.

That makes sense.

Since the main purpose of that part of the Python API is to offer an
opaque handle to where the context locals store their values,
something semantically neutral like "State" may work:

- ContextLocal: read/write API
- ContextLocalState: where ContextLocal instances actually store things
- ExecutionContext: nested stack of context local states

The attribute on generators and coroutines could then be called
"__context_locals__", and that would either be None (indicating that
any context local references will just use the already active context
local storage), or else it would be set to a ContextLocalState
instance (indicate that starting & stopping the operation will push &
pop the given context local state).

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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Greg Ewing

Barry Warsaw wrote:

I actually
think Python’s scoping rules are fairly easy to grasp,


The problem is that the word "scope", as generally used in
relation to programming languages, has to do with visibility
of names. A variable is "in scope" at a particular point in the
code if you can acccess it just by writing its name there.
The things we're talking about are never "in scope" in that
sense.

What we have is something similar to a dynamic scope, but
a special action is required to access bindings in it. I can't
think of any established term for things like that.

The closest I'ves seen is one dialect of Scheme that called
it a "fluid environment". In that dialect, fluid-let didn't
create bindings in the normal scope, and you had to use
specific functions to access them.

--
Greg
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Greg Ewing

Barry Warsaw wrote:

This is my problem with using "Context" for this PEP.  Although I can't
keep up with all names being thrown around,


Not sure whether it helps, but a similar concept in
some Scheme dialects is called a "fluid binding".

e.g. Section 5.4 of http://www.scheme.com/csug8/binding.html

It's not quite the same thing as we're talking about
here (the names bound exist in the normal name lookup
scope rather than a separate namespace) but maybe some
of the terminology could be adapted.

--
Greg
___
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 550 v3 naming

2017-08-24 Thread Eric Snow
On Thu, Aug 24, 2017 at 5:37 AM, Nick Coghlan  wrote:
> Migrating a (variant of a) naming subthread from python-ideas over to
> here, does the following sound plausible to anyone else?:
>
> ContextLocal - read/write access API (via get()/set() methods)
> ContextLocalNamespace - active mapping that CL.get()/set() manipulates
> ExecutionContext - current stack of context local namespaces

Overall it makes sense.  The following derivative might be more clear:

ContextLocal
ContextLocals
ChainedContextLocals (or some variation explicitly calling out the chaining)

Alternatively, similar to other suggestions:

ContextVar
ContextVars
ChainedContextVars

I also think "state" helps disambiguate "context":

ContextVar
ContextState
ChainedContextState

or:

ContextVar
ContextVars
ContextState (perhaps a little too ambiguous without the explicit "chained")

-eric
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Antoine Pitrou
On Thu, 24 Aug 2017 17:06:09 -0400
Barry Warsaw  wrote:
> On Aug 24, 2017, at 16:01, francismb  wrote:
> > On 08/24/2017 03:52 PM, Barry Warsaw wrote:  
> >> Guido van Rossum wrote:  
> >>> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
> >>> 
> >>> I worry that that's going to lead more people astray thinking this has
> >>> something to do with contextlib, which it really doesn't (it's much more
> >>> closely related to threading.local()).  
> >>   
> > If it's hard to find a name due collision with related meanings or
> > already taken buckets then I would suggest just inventing a new word. An
> > artificial one.
> > 
> > What do you thing?  
> 
> I propose RaymondLuxuryYach_t, but we’ll have to pronounce it 
> ThroatwobblerMangrove.

Sorry, but I think we should prononce it ThroatwobblerMangrove.

Regards

Antoine.


___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Barry Warsaw
On Aug 24, 2017, at 16:01, francismb  wrote:
> On 08/24/2017 03:52 PM, Barry Warsaw wrote:
>> Guido van Rossum wrote:
>>> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
>>> 
>>> I worry that that's going to lead more people astray thinking this has
>>> something to do with contextlib, which it really doesn't (it's much more
>>> closely related to threading.local()).
>> 
> If it's hard to find a name due collision with related meanings or
> already taken buckets then I would suggest just inventing a new word. An
> artificial one.
> 
> What do you thing?

I propose RaymondLuxuryYach_t, but we’ll have to pronounce it 
ThroatwobblerMangrove.

import-dinsdale-ly y’rs,
-Barry



signature.asc
Description: Message signed with OpenPGP
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread francismb
Hi,

On 08/24/2017 03:52 PM, Barry Warsaw wrote:
> Guido van Rossum wrote:
>> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
>>
>> I worry that that's going to lead more people astray thinking this has
>> something to do with contextlib, which it really doesn't (it's much more
>> closely related to threading.local()).
> 
If it's hard to find a name due collision with related meanings or
already taken buckets then I would suggest just inventing a new word. An
artificial one.

What do you thing?

Thanks,
--francis

___
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] python issue27584 AF_VSOCK support

2017-08-24 Thread Cathy Avery

On 08/17/2017 05:38 PM, Christian Heimes wrote:

On 2017-08-17 14:21, Cathy Avery wrote:

Hi,

I have a python pull request https://github.com/python/cpython/pull/2489
that introduces AF_VSOCK to the python C socket module.  Unfortunately
things have gone quiet for several weeks. Since I am new to this process
I am unclear on what to expect as the next steps. I believe I have
addressed all issues. If I am mistaken please let me know. A real
functioning test setup is a bit painful and I would be happy to help in
anyway I can. The Microsoft Hyper V team is now introducing support of
vsock in the upstream linux kernel so its adoption is spreading amongst
the various hypervisors.

Any guidance on the basic timelines would be very helpful.

Hi Cathy,

thanks for your contribution! Your patch looks mostly fine. I pointed
out some minor issues in my review.

Regards,
Christian





Thanks! I'm going to push it soon. I think I got everything.
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Eric Snow
On Thu, Aug 24, 2017 at 8:23 AM, Yury Selivanov  wrote:
> Contrary to scoping, the programmer is much less likely to deal with
> Execution Context.  How often do we use "threading.local()"?

This is an important point.  PEP 550 is targeting library authors,
right?  Most folks will not be interacting with the new functionality
except perhaps indirectly via context managers.  So I'm not convinced
that naming collisions with more commonly used concepts is as much a
concern, particularly because of conceptual similarity.  However, if
the functionality of the PEP would be used more commonly then the
naming would be a stronger concern.

-eric
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Eric Snow
On Thu, Aug 24, 2017 at 7:52 AM, Barry Warsaw  wrote:
> Guido van Rossum wrote:
>> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
>>
>> I worry that that's going to lead more people astray thinking this has
>> something to do with contextlib, which it really doesn't (it's much more
>> closely related to threading.local()).
>
> This is my problem with using "Context" for this PEP.  Although I can't
> keep up with all names being thrown around, it seems to me that in
> Python we already have a well-established meaning for "contexts" --
> context managers, and the protocols they implement as they participate
> in `with` statements.  We have contextlib which reinforces this.  What's
> being proposed in PEP 550 is so far removed from this concept that I
> think it's just going to cause confusion (well, it does in me anyway!).

The precedent (and perhaps inspiration) here lies in decimal.context
[1] and ssl.SSLContext [2].  email.Policy [3] qualifies in spirit, as
does the import state [4]. Each encapsulates the state of some
subsystem.  They can be enabled in the current thread via a context
manager.  (Well, only the first two, but the latter two are strong
candidates.)  They are each specific to a *logical* execution context.
Most notably, each is implicit global state in the current thread of
execution.

PEP 550, if I've understood right, is all about supporting these
contexts in other logical threads of execution than just Python/OS
threads (e.g. async, generators).  Given all that, "context" is an
understandable name to use here.

Personally, I'm still on the fence on if "context" fits in the name.
:)  None of the proposed names have felt quite right thus far, which
is probably why we're still talking about it! :)

>
> To me, the functionality proposed in PEP 550 feels more like a "scope"
> than a "context".  Unlike a lexical scope, it can't be inferred from the
> layout of the source code.  It's more of a dynamic "execution scope" and
> the stacking of "local execution scopes" reinforces that for me.  You
> use a key to find a value in the current execution scope, and it chains
> up until the key is found or you've reached the top of the local
> execution (defined as the thread start, etc.).

"scope" fits because it's all about chained lookup in implicit
namespaces.  However, to me the focus of PEP 550 is on the context
(encapsulated state) more than the chaining.

>
> One other suggestion: maybe we shouldn't put these new functions in sys,
> but instead put them in their own module?  It feels analogous to the gc
> module; all those functions could have gone in sys since they query and
> effect the Python runtime system, but it makes more sense (and improves
> the naming) by putting them in their own module.  It also segregates the
> functionality so that sys doesn't become a catchall that overloads you
> when you're reading through the sys module documentation.

+1

-eric

[1] https://docs.python.org/3/library/ssl.html#ssl.SSLContext
[2] https://docs.python.org/3/library/decimal.html#context-objects
[3] https://docs.python.org/3/library/email.policy.html
[4] https://www.python.org/dev/peps/pep-0406/
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Ethan Furman

On 08/24/2017 06:52 AM, Barry Warsaw wrote:


To me, the functionality proposed in PEP 550 feels more like a "scope"
than a "context".  Unlike a lexical scope, it can't be inferred from the
layout of the source code.  It's more of a dynamic "execution scope" and
the stacking of "local execution scopes" reinforces that for me.  You
use a key to find a value in the current execution scope, and it chains
up until the key is found or you've reached the top of the local
execution (defined as the thread start, etc.).


Scope and dynamic certainly feel like the important concepts in PEP 550, and Guido (IIRC) has already said these 
functions do not belong in contextlib, so context may not be a good piece of the name.


Some various ideas:

- ExecutionScope, LocalScope
- DynamicScope, ScopeLocals
- DynamicExecutionScope, DynamicLocals
- DynamicExecutionScope, ExecutionLocals
- DynamicExecutionScope, ScopeLocals

--
~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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Yury Selivanov
On Thu, Aug 24, 2017 at 10:38 AM, Barry Warsaw  wrote:
[..]

I'll snip the naming discussion for now, I'm really curious to see
what other people will say.

> A different tack would more closely align with PEP 550’s heritage in 
> thread-local storage, calling these things “execution storage”.  I think I 
> read Guido suggest elsewhere using a namespace here so that in common code 
> you’d only have to change the “threading.local()” call to migrate to PEP 550. 
>  It might be neat if you could do something like:
>
> import execution
> els = execution.local()
> els.x = 1

A couple of relevant updates on this topic in old python-ideas threads
(I'm not sure you've seen them):

https://mail.python.org/pipermail/python-ideas/2017-August/046888.html
https://mail.python.org/pipermail/python-ideas/2017-August/046889.html

Unfortunately it's not feasible to re-use the "local()" idea for PEP
550.  The "local()" semantics imposes many constraints and
complexities to the design, while offering only "users already know
it" argument for it.

And even if we had "execution.local()" API, it would not be safe to
always replace every "theading.local()" with it. Sometimes what you
need is an actual TLS.  Sometimes your design actually depends on it,
even if you are not aware of that.  Updating existing libraries to use
PEP 550 should be a very conscious decision, simply because it has
different semantics/guarantees.

Y
___
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 550 leak-in vs leak-out, why not just a ChainMap

2017-08-24 Thread Yury Selivanov
On Thu, Aug 24, 2017 at 10:05 AM, Jim J. Jewett  wrote:
> On Thu, Aug 24, 2017 at 1:12 AM, Yury Selivanov > On Thu, Aug 24, 2017
> at 12:32 AM, Jim J. Jewett  wrote:
>
>> The key requirement for using immutable datastructures is to make
>> "get_execution_context" operation fast.
>
> Do you really need the whole execution context, or do you just need
> the current value of a specific key?  (Or, sometimes, the writable
> portion of the context.)

We really need a snapshot of all keys/values.  If we have the following "chain":

   EC = [{'a': 'b'}, {'spam': 'ham'}, {}, {'a': 'foo', 'num': 42}]

we need sys.get_execution_context() to return this:

  {'spam': 'ham', 'a': 'foo', 'num': 42}

To do this with chain map and mutable maps, you need to traverse the
whole chain and merge all dicts -- this is very expensive.  Immutable
datastructures make it possible to avoid merge and traverse (in most
cases) so the operation becomes cheap.

Don't forget, that the EC is a *dynamic* stack -- a generator starts,
it pushes its LogicalContext, etc.

Without a way to get a full "snapshot" of the EC we can't support
asynchronous tasks:

If you look at this small example:

foo = new_context_key()

async def nested():
await asyncio.sleep(1)
print(foo.get())

async def outer():
foo.set(1)
await nested()
foo.set(1000)

l = asyncio.get_event_loop()
l.create_task(outer())
l.run_forever()

If will print "1", as "nested()" coroutine will see the "foo" key when
it's awaited.

Now let's say we want to refactor this snipped and run the "nested()"
coroutine with a timeout:

foo = new_context_key()

async def nested():
await asyncio.sleep(1)
print(foo.get())

async def outer():
foo.set(1)
await asyncio.wait_for(nested(), 10)  # !!!
foo.set(1000)

l = asyncio.get_event_loop()
l.create_task(outer())
l.run_forever()

So we wrap our `nested()` in a `wait_for()`, which creates a new
asynchronous tasks to run `nested()`.  That task will now execute on
its own, separately from the task that runs `outer()`.  So we need to
somehow capture the full EC at the moment `wait_for()` was called, and
use that EC to run `nested()` within it.  If we don't do this, the
refactored code would print "1000", instead of "1".

If asynchronous tasks topic is not enough: suppose you want to write a
wrapper on top of concurrent.futures.ThreadPoolExecutor to offload
some calculation to a threadpool.  If you can "snapshot" the EC, you
can do it: when you schedule a job, the EC is captured, and it is a
guarantee that it will not be mutated before the job is executed.  And
it's also guaranteed that the job will not randomly mutate the EC of
the code that scheduled it.

>>  Currently, the PEP doesn't do
>> a good job at explaining why we need that operation and why it will be
>> used by asyncio.Task and call_soon, so I understand the confusion.
>
> OK, the schedulers need the whole context, but if implemented as a
> ChainMap (instead of per-key),

I think you are a bit confused here (or I don't follow you) with the
"per-key" ConceptKey design.

With ConceptKeys:

key = new_concept_key('spam')
key.set('a')
# EC = [..., {key: 'a'}]

without:

ec.set('key', 'a')
# EC = [..., {'key': 'a'}]

ConceptKey is an extra indirection layer that allows for granular
caching and avoids the names clashing.

> isn't that just a single constant?  As
> in, don't they always schedule to the same thread?  And when they need
> another map, isn't that because the required context is already
> available from whichever code requested the scheduling?
>
>>> (A)  How many values do you expect a typical generator to use?  The
>>> django survey suggested mostly 0, sometimes 1, occasionally 2.  So
>>> caching the values of all possible keys probably won't pay off.
>
>> Not many, but caching is still as important, because some API users
>> want the "get()" operation to be as fast as possible under all
>> conditions.
>
> Sure, but only because they view it as a hot path; if the cost of that
> speedup is slowing down another hot path, like scheduling the
> generator in the first place, it may not be worth it.
>
> According to the PEP timings, HAMT doesn't beat a copy-on-write dict
> until over 100 items, and never beats a regular dict.That suggests
> to me that it won't actually help the overall speed for a typical (as
> opposed to worst-case) process.

It's a bit more complicated, unfortunately.

The "100 items" it true when we can just memcpy all keys/values of the
dict when we want to clone it.  I've proposed a patch to do that, and
it works.

The old implementation of "dict.copy()" created a new dict, iterated
over items of the old dict, and inserted them to the new one.  This 5x
slower than memcpy.

The subtle difference is that the memcpy implementation does not
resize the dict. The resize is needed when we delete items from it
(which will happen with

Re: [Python-Dev] PEP 550 v3 naming

2017-08-24 Thread Guido van Rossum
It shouldn't be called a namespace unless the dominant access is via
attributes.

On Thu, Aug 24, 2017 at 4:37 AM, Nick Coghlan  wrote:

> On 24 August 2017 at 08:47, Ethan Furman  wrote:
> >
> > ContextVars is actually a different name for LogicalContext.  So it would
> > be:
> >
> >   ExecutionContext = [ContextVars()[, ContextVars()[ ...]]]
> >
> > and you get the (thread.local similar) ContextVars by
> >
> >   context_vars = sys.get_context_vars()   # or whatever
> >   context_vars.verbose = ...
>
> Migrating a (variant of a) naming subthread from python-ideas over to
> here, does the following sound plausible to anyone else?:
>
> ContextLocal - read/write access API (via get()/set() methods)
> ContextLocalNamespace - active mapping that CL.get()/set() manipulates
> ExecutionContext - current stack of context local namespaces
>
> Building a threading.local() style helper API would then look something
> like:
>
> class ContextLocals:
> def __init__(self, key_prefix):
> self._key_prefix = key_prefix
>
> def __getattr__(self, attr):
> debugging_name = "{}.{}".format(self._key_prefix, attr)
> self.__dict__[attr] = new_local =
> sys.new_context_local(debugging_name)
> return new_local
>
> def __setattr__(self, attr, value):
> getattr(self, attr).set(value)
>
> def __delattr__(self, attr):
> getattr(self, attr).set(None)
>
> my_state = ContextLocals(__name__)
>
> 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/
> 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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Paul Moore
On 24 August 2017 at 15:38, Barry Warsaw  wrote:
> Yes, but in conversations about Python, the term “context” (in the context of 
> context managers) comes up way more often than the term “scope”.  I actually 
> think Python’s scoping rules are fairly easy to grasp, as there aren’t that 
> many levels or ways to access them, and the natural, common interactions are 
> basically implicit when thinking about the code you’re writing.
>
> So while “context”, “environment”, and “scope” are certainly overloaded terms 
> in Python, the first two have very specific existing, commonplace constructs 
> within Python, and “scope” is both the least overloaded of the three and most 
> closely matches what is actually going on.
>
> A different tack would more closely align with PEP 550’s heritage in 
> thread-local storage, calling these things “execution storage”.  I think I 
> read Guido suggest elsewhere using a namespace here so that in common code 
> you’d only have to change the “threading.local()” call to migrate to PEP 550. 
>  It might be neat if you could do something like:

I strongly agree with Barry's reservations about using the term
"context" here. I've not been following the discussion (I was away
when it started and there's too many emails to go through to catch up)
but I've found the use of the term "context" to be a particular
problem in trying to understand what's going on just skimming the
messages.

I don't have a strong opinion on what name should be used, but I am
definitely against using the term "context".

Paul
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Barry Warsaw
On Aug 24, 2017, at 10:23, Yury Selivanov  wrote:
> 
> On Thu, Aug 24, 2017 at 9:52 AM, Barry Warsaw  wrote:
>> Guido van Rossum wrote:
>>> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
>>> 
>>> I worry that that's going to lead more people astray thinking this has
>>> something to do with contextlib, which it really doesn't (it's much more
>>> closely related to threading.local()).
>> 
>> This is my problem with using "Context" for this PEP.  Although I can't
>> keep up with all names being thrown around, it seems to me that in
>> Python we already have a well-established meaning for "contexts" --
>> context managers, and the protocols they implement as they participate
>> in `with` statements.  We have contextlib which reinforces this.  What's
>> being proposed in PEP 550 is so far removed from this concept that I
>> think it's just going to cause confusion (well, it does in me anyway!).
> 
> Although nobody refers to context managers as "context", they are
> always called with on of the following: "context manager", "CM",
> "context manager protocol".  PEP 550 just introduces a concept of
> "context", that "context managers" will be able to manage.
> 
>> 
>> To me, the functionality proposed in PEP 550 feels more like a "scope"
>> than a "context".  Unlike a lexical scope, it can't be inferred from the
>> layout of the source code.  It's more of a dynamic "execution scope" and
>> the stacking of "local execution scopes" reinforces that for me.  You
>> use a key to find a value in the current execution scope, and it chains
>> up until the key is found or you've reached the top of the local
>> execution (defined as the thread start, etc.).
> 
> Yes, what PEP 550 proposes can be seen as a new scoping mechanism. But
> calling it a "scope" or "dynamic scope" would be a mistake (IMHO), as
> Python scoping is already a complex topic (with locals, nonlocals,
> globals, etc).
> 
> Contrary to scoping, the programmer is much less likely to deal with
> Execution Context.  How often do we use "threading.local()”?

Yes, but in conversations about Python, the term “context” (in the context of 
context managers) comes up way more often than the term “scope”.  I actually 
think Python’s scoping rules are fairly easy to grasp, as there aren’t that 
many levels or ways to access them, and the natural, common interactions are 
basically implicit when thinking about the code you’re writing.

So while “context”, “environment”, and “scope” are certainly overloaded terms 
in Python, the first two have very specific existing, commonplace constructs 
within Python, and “scope” is both the least overloaded of the three and most 
closely matches what is actually going on.

A different tack would more closely align with PEP 550’s heritage in 
thread-local storage, calling these things “execution storage”.  I think I read 
Guido suggest elsewhere using a namespace here so that in common code you’d 
only have to change the “threading.local()” call to migrate to PEP 550.  It 
might be neat if you could do something like:

import execution
els = execution.local()
els.x = 1

By calling it “execution local storage” you’re also providing a nicer cognitive 
bridge from “thread local storage”, a concept anybody diving into this stuff 
will already understand pretty innately.  No need to get fancy, we just think 
“Oh, I know what thread local storage is, and this seems related but slightly 
different, so now I basically understand what execution local storage is”.

Cheers,
-Barry



signature.asc
Description: Message signed with OpenPGP
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Yury Selivanov
On Thu, Aug 24, 2017 at 9:52 AM, Barry Warsaw  wrote:
> Guido van Rossum wrote:
>> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
>>
>> I worry that that's going to lead more people astray thinking this has
>> something to do with contextlib, which it really doesn't (it's much more
>> closely related to threading.local()).
>
> This is my problem with using "Context" for this PEP.  Although I can't
> keep up with all names being thrown around, it seems to me that in
> Python we already have a well-established meaning for "contexts" --
> context managers, and the protocols they implement as they participate
> in `with` statements.  We have contextlib which reinforces this.  What's
> being proposed in PEP 550 is so far removed from this concept that I
> think it's just going to cause confusion (well, it does in me anyway!).

Although nobody refers to context managers as "context", they are
always called with on of the following: "context manager", "CM",
"context manager protocol".  PEP 550 just introduces a concept of
"context", that "context managers" will be able to manage.

>
> To me, the functionality proposed in PEP 550 feels more like a "scope"
> than a "context".  Unlike a lexical scope, it can't be inferred from the
> layout of the source code.  It's more of a dynamic "execution scope" and
> the stacking of "local execution scopes" reinforces that for me.  You
> use a key to find a value in the current execution scope, and it chains
> up until the key is found or you've reached the top of the local
> execution (defined as the thread start, etc.).

Yes, what PEP 550 proposes can be seen as a new scoping mechanism. But
calling it a "scope" or "dynamic scope" would be a mistake (IMHO), as
Python scoping is already a complex topic (with locals, nonlocals,
globals, etc).

Contrary to scoping, the programmer is much less likely to deal with
Execution Context.  How often do we use "threading.local()"?

> One other suggestion: maybe we shouldn't put these new functions in sys,
> but instead put them in their own module?  It feels analogous to the gc
> module; all those functions could have gone in sys since they query and
> effect the Python runtime system, but it makes more sense (and improves
> the naming) by putting them in their own module.  It also segregates the
> functionality so that sys doesn't become a catchall that overloads you
> when you're reading through the sys module documentation.

I'm myself not a big fan of jamming all PEP 550 APIs into the sys
module. We just need to come up with a good name.

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 550 leak-in vs leak-out, why not just a ChainMap

2017-08-24 Thread Jim J. Jewett
On Thu, Aug 24, 2017 at 1:12 AM, Yury Selivanov > On Thu, Aug 24, 2017
at 12:32 AM, Jim J. Jewett  wrote:

> The key requirement for using immutable datastructures is to make
> "get_execution_context" operation fast.

Do you really need the whole execution context, or do you just need
the current value of a specific key?  (Or, sometimes, the writable
portion of the context.)


>  Currently, the PEP doesn't do
> a good job at explaining why we need that operation and why it will be
> used by asyncio.Task and call_soon, so I understand the confusion.

OK, the schedulers need the whole context, but if implemented as a
ChainMap (instead of per-key), isn't that just a single constant?  As
in, don't they always schedule to the same thread?  And when they need
another map, isn't that because the required context is already
available from whichever code requested the scheduling?

>> (A)  How many values do you expect a typical generator to use?  The
>> django survey suggested mostly 0, sometimes 1, occasionally 2.  So
>> caching the values of all possible keys probably won't pay off.

> Not many, but caching is still as important, because some API users
> want the "get()" operation to be as fast as possible under all
> conditions.

Sure, but only because they view it as a hot path; if the cost of that
speedup is slowing down another hot path, like scheduling the
generator in the first place, it may not be worth it.

According to the PEP timings, HAMT doesn't beat a copy-on-write dict
until over 100 items, and never beats a regular dict.That suggests
to me that it won't actually help the overall speed for a typical (as
opposed to worst-case) process.

>> And, of course, using a ChainMap means that the keys do NOT have to be
>> predefined ... so the Key class really can be skipped.

> The first version of the PEP had no ContextKey object and the most
> popular complaint about it was that the key names will clash.

That is true of any global registry.  Thus the use of keys with
prefixes like com.sun.

The only thing pre-declaring a ContextKey buys in terms of clashes is
that a sophisticated scheduler would have less difficulty figuring out
which clashes will cause thrashing in the cache.

Or are you suggesting that the key can only be declared once (as
opposed to once per piece of code), so that the second framework to
use the same name will see a RuntimeError?

-jJ
___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Antoine Pitrou
On Thu, 24 Aug 2017 09:52:47 -0400
Barry Warsaw  wrote:
> 
> To me, the functionality proposed in PEP 550 feels more like a "scope"
> than a "context".

I would call it "environment" myself, but that risks confusion with
environment variables.

Perhaps "dynamic environment" would remove the confusion.

> One other suggestion: maybe we shouldn't put these new functions in sys,
> but instead put them in their own module?  It feels analogous to the gc
> module; all those functions could have gone in sys since they query and
> effect the Python runtime system, but it makes more sense (and improves
> the naming) by putting them in their own module.  It also segregates the
> functionality so that sys doesn't become a catchall that overloads you
> when you're reading through the sys module documentation.

+1 from me.

Regards

Antoine.


___
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] Scope, not context? (was Re: PEP 550 v3 naming)

2017-08-24 Thread Barry Warsaw
Guido van Rossum wrote:
> On Tue, Aug 22, 2017 at 7:12 PM, Nathaniel Smith  wrote:
> 
> I worry that that's going to lead more people astray thinking this has
> something to do with contextlib, which it really doesn't (it's much more
> closely related to threading.local()).

This is my problem with using "Context" for this PEP.  Although I can't
keep up with all names being thrown around, it seems to me that in
Python we already have a well-established meaning for "contexts" --
context managers, and the protocols they implement as they participate
in `with` statements.  We have contextlib which reinforces this.  What's
being proposed in PEP 550 is so far removed from this concept that I
think it's just going to cause confusion (well, it does in me anyway!).

To me, the functionality proposed in PEP 550 feels more like a "scope"
than a "context".  Unlike a lexical scope, it can't be inferred from the
layout of the source code.  It's more of a dynamic "execution scope" and
the stacking of "local execution scopes" reinforces that for me.  You
use a key to find a value in the current execution scope, and it chains
up until the key is found or you've reached the top of the local
execution (defined as the thread start, etc.).

One other suggestion: maybe we shouldn't put these new functions in sys,
but instead put them in their own module?  It feels analogous to the gc
module; all those functions could have gone in sys since they query and
effect the Python runtime system, but it makes more sense (and improves
the naming) by putting them in their own module.  It also segregates the
functionality so that sys doesn't become a catchall that overloads you
when you're reading through the sys module documentation.

Cheers,
-Barry

___
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 550 v3 naming

2017-08-24 Thread Nick Coghlan
On 24 August 2017 at 08:47, Ethan Furman  wrote:
>
> ContextVars is actually a different name for LogicalContext.  So it would
> be:
>
>   ExecutionContext = [ContextVars()[, ContextVars()[ ...]]]
>
> and you get the (thread.local similar) ContextVars by
>
>   context_vars = sys.get_context_vars()   # or whatever
>   context_vars.verbose = ...

Migrating a (variant of a) naming subthread from python-ideas over to
here, does the following sound plausible to anyone else?:

ContextLocal - read/write access API (via get()/set() methods)
ContextLocalNamespace - active mapping that CL.get()/set() manipulates
ExecutionContext - current stack of context local namespaces

Building a threading.local() style helper API would then look something like:

class ContextLocals:
def __init__(self, key_prefix):
self._key_prefix = key_prefix

def __getattr__(self, attr):
debugging_name = "{}.{}".format(self._key_prefix, attr)
self.__dict__[attr] = new_local =
sys.new_context_local(debugging_name)
return new_local

def __setattr__(self, attr, value):
getattr(self, attr).set(value)

def __delattr__(self, attr):
getattr(self, attr).set(None)

my_state = ContextLocals(__name__)

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 550 v3 naming

2017-08-24 Thread Nathaniel Smith
On Thu, Aug 24, 2017 at 1:22 AM, Nick Coghlan  wrote:
> On 24 August 2017 at 02:19, Yury Selivanov  wrote:
>> I think that "implicit context" is not an accurate description of what
>> LogicalContext is.
>>
>> "implicit context" only makes sense when we talk about decimal
>> context.  For instance, in:
>>
>> Decimal(1) + Decimal(2)
>>
>> decimal context is implicit.  But this is "implicit" from the
>> standpoint of that code.  Decimal will manage its context
>> *explicitly*.
>>
>> Fixing decimal context is only one part of the PEP though.  EC will
>> also allow to implement asynchronous task locals:
>>
>> current_request = new_context_key()
>>
>> async def handle_http_request(request):
>>  current_request.set(request)
>>
>> Here we explicitly set and will explicitly get values from the EC.  We
>> will explicitly manage the EC in asyncio.Task and when we schedule
>> callbacks.
>
> The implicit behaviour that "implicit context" refers to is the fact
> that if you look at an isolated snippet of code, you have no idea what
> context you're actually going to be querying or modifying - that's
> implicit in the execution of the whole program.

How about: RuntimeContext and RuntimeContextStack

-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] PEP 550 leak-in vs leak-out, why not just a ChainMap

2017-08-24 Thread Nathaniel Smith
On Wed, Aug 23, 2017 at 9:32 PM, Jim J. Jewett  wrote:
>> While the context is defined conceptually as a nested chain of
>> key:value mappings, we avoid using the mapping syntax because of the
>> way the values can shift dynamically out from under you based on who
>> called you
> ...
>> instead of having the problem of changes inside the
>> generator leaking out, we instead had the problem of
>> changes outside the generator *not* making their way in
>
> I still don't see how this is different from a ChainMap.
>
> If you are using a stack(chain) of [d_global, d_thread, d_A, d_B, d_C,
> d_mine]  maps as your implicit context, then a change to d_thread map
> (that some other code could make) will be visible unless it is masked.
>
> Similarly, if the fallback for d_C changes from d_B to d_B1 (which
> points directly to d_thread), that will be visible for any keys that
> were previously resolved in d_A or d_B, or are now resolved in dB1.
>
> Those seem like exactly the cases that would (and should) cause
> "shifting values".
>
> This does mean that you can't cache everything in the localmost map,
> but that is a problem with the optimization regardless of how the
> implementation is done.

It's crucial that the only thing that can effect the result of calling
ContextKey.get() is other method calls on that same ContextKey within
the same thread. That's what enables ContextKey to efficiently cache
repeated lookups, which is an important optimization for code like
decimal or numpy that needs to access their local context *extremely*
quickly (like, a dict lookup is too slow). In fact this caching trick
is just preserving what decimal does right now in their thread-local
handling (because accessing the threadstate dict is too slow for
them).

So we can't expose any kind of mutable API to individual maps, because
then someone might call __setitem__ on some map that's lower down in
the stack, and break caching.

> And, of course, using a ChainMap means that the keys do NOT have to be
> predefined ... so the Key class really can be skipped.

The motivations for the Key class are to eliminate the need to worry
about accidental key collisions between unrelated libraries, to
provide some important optimizations (as per above), and to make it
easy and natural to provide convenient APIs like for saving and
restoring the state of a value inside a context manager. Those are all
orthogonal to whether the underlying structure is implemented as a
ChainMap or as something more specialized.

But I tend to agree with your general argument that the current PEP is
trying a bit too hard to hide away all this structure where no-one can
see it. The above constraints mean that simply exposing a ChainMap as
the public API is probably a bad idea. Even if there are compelling
performance advantages to fancy immutable-HAMT implementation (I'm in
wait-and-see mode on this myself), then there are still a lot more
introspection-y operations that could be provided, like:

- make a LocalContext out of a {ContextKey: value} dict
- get a {ContextKey: value} dict out of a LocalContext
- get the underlying list of LocalContexts out of an ExecutionContext
- create an ExecutionContext out of a list of LocalContexts
- given a ContextKey and a LocalContext, get the current value of the
key in the context
- given a ContextKey and an ExecutionContext, get out a list of values
at each level

-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] PEP 550 v3 naming

2017-08-24 Thread Nick Coghlan
On 24 August 2017 at 02:19, Yury Selivanov  wrote:
> I think that "implicit context" is not an accurate description of what
> LogicalContext is.
>
> "implicit context" only makes sense when we talk about decimal
> context.  For instance, in:
>
> Decimal(1) + Decimal(2)
>
> decimal context is implicit.  But this is "implicit" from the
> standpoint of that code.  Decimal will manage its context
> *explicitly*.
>
> Fixing decimal context is only one part of the PEP though.  EC will
> also allow to implement asynchronous task locals:
>
> current_request = new_context_key()
>
> async def handle_http_request(request):
>  current_request.set(request)
>
> Here we explicitly set and will explicitly get values from the EC.  We
> will explicitly manage the EC in asyncio.Task and when we schedule
> callbacks.

The implicit behaviour that "implicit context" refers to is the fact
that if you look at an isolated snippet of code, you have no idea what
context you're actually going to be querying or modifying - that's
implicit in the execution of the whole program.

As a user of the read/write API though, you shouldn't need to care all
that much - the whole point of PEP 550 is to define default behaviours
and guidelines such that it will be something sensible.

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 550 v3 naming

2017-08-24 Thread Antoine Pitrou
On Wed, 23 Aug 2017 14:27:55 -0400
Yury Selivanov  wrote:
> 
> Yeah.. I like TaskContext when it's applied to asynchronous code. It
> doesn't really work for generators because we never refer to
> generators as tasks.
> 
> Out of what was proposed so far to replace Logical Context:
> 
> 1. DynamicContext: close to "dynamic scoping", but tries to avoid
> mentioning "scopes". There are only a few languages where dynamic
> scoping is implemented, so people are generally not aware of it.
> 
> 2. ContextFrame and all frame-related names: implies that EC is
> somehow implemented on top of frames or is frame-specific (which is
> not always true).
> 
> 3. ImplicitContext: covers one specific property observed from
> specific examples.  Context in PEP 550 is managed explicitly in some
> cases. There are many use cases when API users will be working with it
> explicitly too (to wrirte/read data from it). FWIW I believe that
> "ExplicitContext" would be more accurate than "ImplicitContext".
> 
> 4. LocalContext: we use "local" to describe local variables and
> scoping in Python, we want to avoid any confusion here.
> 
> 5. TaskContext: works for asynchronous tasks, but not for generators.
> 
> I don't think that replacing LogicalContext with any name in this list
> will make any improvement.

I think you have a point.  Though every time I want to type "logical
context" it seems my fingers slip and type "local context" instead :-)

Now remains the question of why the logical context stack is named
"execution context" and not "logical context stack" (or "logical
context chain" to keep the ChainMap analogy) :-)

Regards

Antoine.
___
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