> On Jan 3, 2018, at 12:26 PM, Victor Stinner <victor.stin...@gmail.com> wrote:
> 
> Le 3 janv. 2018 06:05, "Yury Selivanov" <yselivanov...@gmail.com> a écrit :
> tuples in Python are immutable, but you can have a tuple with a dict as its 
> single element. The tuple is immutable, the dict is mutable.
> 
> At the C level we have APIs that can mutate a tuple though.
> 
> Now, tuple is not a direct analogy to Context, but there are some parallels.  
> Context is a container like tuple, with some additional APIs on top.
> 
> Sorry, I don't think that it's a good analogy. Context.run() is a public 
> method accessible in Python which allows to modify the context. A tuple 
> doesn't have such method.
> 
> While it's technically possible to modify a tuple or a str at C level, it's a 
> bad practice leading to complex bugs when it's not done carefully: see 
> https://bugs.python.org/issue30156 property_descr_get() optimization was 
> fixed twice but still has a bug. I proposed a PR to remove the hack.
> 
>> Why Context could not inherit from MutableMapping? (Allow ctx.set(var, 
>> value) and ctx [var] = value.) Is it just to keep the API small: changes 
>> should only be made using var.set()?
> 
> Because that would be confusing to end users.
> 
>   ctx = copy_context()
>   ctx[var] = something
> 
> What did we just do?  Did we modify the 'var' in the code that is currently 
> executing? No, you still need to call Context.run to see the new value for 
> var.
> 
> IMHO it's easy to understand that modifying a *copy* of the current context 
> doesn't impact the current context. It's one the first thing to learn when 
> learning Python:
> 
> a = [1, 2]
> b = a.copy()
> b.append(3)
> assert a == [1, 2]
> assert b == [1, 2, 3]
> 
> Another problem is that MutableMapping defines a __delitem__ method, which i 
> don't want the Context to implement.
> 
> I wouldn't be shocked if "del ctx [var]" would raise an exception.
> 
> I almost never use del anyway. I prefer to assign a variable to None, since 
> "del var" looks like C++ destructor whereas it's more complex than a direct 
> call to the destructor.
> 
> But it's annoying to have to call a function with Context.run() whereas 
> context is just a mutable mapping. It seems overkill to me to have to call 
> run() to modify a context variable:

Do you have any use case for modifying a variable inside some context?

numpy, decimal, or some sort of tracing for http requests or async frameworks 
like asyncio do not need that.

> run() changes temporarely the context and requires to use the indirect 
> ContextVar API, while I know that ContextVar.set() modifies the context.
> 
> Except of del corner case, I don't see any technical reason to prevent direct 
> modification of a context.
> 
> contextvars isn't new, it extends what we already have: decimal context. And 
> decimal quick start documentation shows how to modify a context and then set 
> it as the current context:
> 

I think you are confusing context in decimal and pep 567.

Decimal context is a mutable object. We use threading.local to store it. With 
pep 567 you will use a context variable behind the scenes to store it.

I think it's incorrect to compare decimal contexts to pep567 in any way.

Yury

> >>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
> >>> setcontext(myothercontext)
> >>> Decimal(1) / Decimal(7)
> Decimal('0.142857142857142857142857142857142857142857142857142857142857')
> 
> https://docs.python.org/dev/library/decimal.html
> 
> Well, technically it doesn't modify a context. An example closer to 
> contextvars would be:
> 
> >>> mycontext = getcontext().copy()
> >>> mycontext.prec = 60
> >>> setcontext(mycontext)
> >>> Decimal(1) / Decimal(7)
> Decimal('0.142857142857142857142857142857142857142857142857142857142857')
> 
> Note: "getcontext().prec = 6" does modify the decimal context directly, and 
> it's the *first* example in the doc. But here contextvars is different since 
> there is no API to get the current API. The lack of API to access directly 
> the current contextvars context is the main difference with decimal context, 
> and I'm fine with that.
> 
> It's easy to see a parallel since decimal context can be copied using 
> Context.copy(), it has also multiple (builtin) "variables", it's just that 
> the API is different (decimal context variables are modified as attributes), 
> and it's possible to set a context using decimal.setcontext().
> 
> Victor
_______________________________________________
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

Reply via email to