Skip to content
Advertisement

Factory for contextvar default value

Setting a dictionary as ContextVar default:

var: ContextVar[dict] = ContextVar('var', default={})

…kinda works, as the dictionary will be available as default, but it always references the same instance, instead of generating a new one for each context.

Do contextvars somehow support factories (for dicts, lists, and alike), as in:

var: ContextVar[dict] = ContextVar('var', default=list)
var: ContextVar[dict] = ContextVar('var', default=lambda: dict())

Or do I just have to do it manually:

var: ContextVar[Optional[dict]] = ContextVar('var', default=None)

...

if not var.get():
    var.set({})

Advertisement

Answer

Apparently ContextVars designed choice was in the direction of providing the low level, barebones, functionality over ease of use.

There is no easy way to get a context-aware namespace, as you intend to do by having the dictionary as default. And also, no option for the default value to use a factory rather than a single object.

The only way to overcome that is to write a class that provides a higher level interface on top of contextvars (or other context-separating mechanism).

I am just working on such a package, although I made no release yet – y main goal is to have a class that act as a free-to-use namespace, just like threading.Local instances. (There is also one class using the mapping interface) – if I get more people using and providing some feedback, I could come faster to a finished form:

https://github.com/jsbueno/extracontext

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement