> 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