On 1/3/2018 11:16 AM, Guido van Rossum       wrote:
                
Maybe I should clarify again what run() does. Here's how I         think of it in pseudo code:
      

      
      
def run(self, func, *args, **kwds):
      
    old = _get_current_context()
      
    new = old.copy()
      
    _set_current_context(new)
      
    try:
      
        return func(*args, **kwds)
      
    finally:
      
        _set_current_context(old)
      

      
         
    
    I find it interesting that self isn't used in the above pseudo-code.     I thought that Context.run() would run the function in the "context"     of self, not in the context of a copy of "current context".
    
    
  
Heh, you're right, I forgot about that. It should be more like this:
def run(self, func, *args, **kwds):
    old = _get_current_context()
    _set_current_context(self)  # <--- changed line
    try:
        return func(*args, **kwds)
    finally:
        _set_current_context(old)

This version, like the PEP,  assumes that the Context object is truly immutable (not just in name) and that you should call it like this:
contextvars.copy_context().run(func, )
The PEP definitely needs to be clearer about this -- right now one has to skip back and forth between the specification and the implementation (and sometimes the introduction) to figure out how things really work. Help is wanted!

-- 
--Guido van Rossum (python.org/~guido) ">

(original) (raw)

On Wed, Jan 3, 2018 at 12:32 PM, Glenn Linderman <v+python@g.nevcal.com> wrote:
On 1/3/2018 11:16 AM, Guido van Rossum wrote:
Maybe I should clarify again what run() does. Here's how I think of it in pseudo code:

def run(self, func, \*args, \*\*kwds):
old = \_get\_current\_context()
new = old.copy()
\_set\_current\_context(new)
try:
return func(\*args, \*\*kwds)
finally:
\_set\_current\_context(old)



I find it interesting that self isn't used in the above pseudo-code. I thought that Context.run() would run the function in the "context" of self, not in the context of a copy of "current context".



Heh, you're right, I forgot about that. It should be more like this:

def run(self, func, \*args, \*\*kwds):
old = \_get\_current\_context()
\_set\_current\_context(self) # <--- changed line
try:
return func(\*args, \*\*kwds)
finally:
\_set\_current\_context(old)

This version, like the PEP, assumes that the Context object is truly immutable (not just in name) and that you should call it like this:

contextvars.copy\_context().run(func, )

The PEP definitely needs to be clearer about this -- right now one has to skip back and forth between the specification and the implementation (and sometimes the introduction) to figure out how things really work. Help is wanted!

--
--Guido van Rossum (python.org/\~guido)