|
""" |
|
In the following code we look at the contextvars.Context object, which is a mapping of ContextVars to their values. |
|
|
|
Whenever you import the contextvars module you'll find that there is 'default' Context created. |
|
|
|
If you set a ContextVar in any modules that have imported the contextvars module, then you'll discover the |
|
default Context is shared between modules and so it'll show the same ContextVar across all modules. |
|
|
|
You can access the default Context by taking a copy of it (see below). |
|
|
|
It's important to realize that defining a ContextVar will not mean it shows up in the Context _unless_ |
|
you set a value onto the ContextVar. Because the following code presumes the earlier code in file 1. |
|
was executed, it means we can see the 'foo' ContextVar that was set. |
|
""" |
|
|
|
ctx = contextvars.copy_context() # <Context at 0x106e23840> |
|
|
|
list(ctx.keys()) # [<ContextVar name='foo' at 0x106f52590>] |
|
list(ctx.items()) # [(<ContextVar name='foo' at 0x106f52590>, 'bar')] |
|
|
|
""" |
|
Context() creates an empty context with no values in it. |
|
""" |
|
|
|
newctx = contextvars.Context() # <Context at 0x106fa2ac0> |
|
|
|
list(newctx.items()) # [] |
|
|
|
""" |
|
Changes can be made to a Context's ContextVar(s) if modified via the contextvars.Context().run() method |
|
|
|
The following code snippet presumes a fresh environment (no previous Context or ContextVars)... |
|
""" |
|
|
|
var = contextvars.ContextVar('foo') |
|
var.set('bar') |
|
|
|
def scope(): |
|
var.set('baz') |
|
print(var.get('foo')) # 'baz' |
|
print(ctx.get(var)) # 'baz' |
|
return "finished" |
|
|
|
ctx = contextvars.copy_context() |
|
|
|
list(ctx.items()) # [(<ContextVar name='foo' at 0x1025a1450>, 'bar')] |
|
|
|
result = ctx.run(scope) # 'finished' |
|
|
|
""" |
|
NOTE: |
|
|
|
If you're just doing a WRITE operation then pass the `.set()` method to `.run()` |
|
|
|
e.g. ctx.run(var.set, 'baz') |
|
""" |
|
|
|
list(ctx.items()) # [(<ContextVar name='foo' at 0x1025a1450>, 'baz')] |
|
|
|
var.get('foo') # 'bar' |
|
|
|
""" |
|
Unforunately the object model is a bit crappy and so it's not easy to get at the internal ContextVars a Context holds. |
|
|
|
I wrote a quick lookup function to help with that... |
|
""" |
|
|
|
import contextvars |
|
from typing import Optional |
|
|
|
|
|
def lookup(ctx: contextvars.Context, key: str) -> Optional[str]: |
|
for i, v in list(ctx.items()): |
|
if i.name == key: |
|
return v |
|
return None |
|
|
|
lookup(ctx, "foo") # 'bar' |