> On Jan 3, 2018, at 12:26 PM, Victor Stinner <[email protected]> wrote:
>
> Le 3 janv. 2018 06:05, "Yury Selivanov" <[email protected]> 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
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com