On Tue, Aug 15, 2017 at 11:53 PM, Jelle Zijlstra <jelle.zijls...@gmail.com> wrote: > Minor suggestion: Could we allow something like > `sys.set_new_context_item(description='mylib.context', > initial_value='spam')`? That would make it easier for type checkers to infer > the type of a ContextItem, and it would save a line of code in the common > case.
This is a really handy feature in general, actually! In fact all of asyncio's thread-locals define initial values (using a trick involving subclassing threading.local), and I recently added this feature to trio.TaskLocal as well just because it's so convenient. However, something that you realize almost immediately when trying to use this is that in many cases, what you actually want is an initial value *factory*. Like, if you write new_context_item(initial_value=[]) then you're going to have a bad time. So, should we support something like new_context_item(initializer=lambda: [])? The semantics are a little bit subtle. I guess it would be something like: if ci.get() goes to find the value and fails at all levels, then we call the factory function and assign its return value to the *deepest* LC, EC[0]. The idea being that we're pretending that the value was there all along in the outermost scope, you just didn't notice before now. > With this modification, the type of new_context_item would be > > @overload > def new_context_item(*, description: str, initial_value: T) -> > ContextItem[T]: ... > @overload > def new_context_item(*, description: str) -> ContextItem[Any]: ... > > If we only allow the second variant, type checkers would need some sort of > special casing to figure out that after .set(), .get() will return the same > type. I'm not super familiar with PEP 484. Would using a factory function instead of an initial value break this type inference? If you want to automatically infer that whatever type I use to initialize the value is the only type it can ever have, is there a way for users to easily override that? Like could I write something like my_ci: ContextItem[int, str] = new_context_item(initial_value=0) ? -n -- Nathaniel J. Smith -- https://vorpus.org _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/