Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python ContextVar: task-local labels without sharing one global binding

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

ContextVar stores a value in the current execution context, allowing tasks to change their binding without overwriting a sibling task’s binding.

Download Python source kit

Operation contract

The parent supplies an import label before creating two tasks. Each task receives that context and temporarily binds its own receipt label. After an explicit scheduling yield, each still sees its own value. Resetting its token restores the previous binding, and the parent label remains unchanged after both tasks finish.

Failure and ownership boundary

Context copying copies bindings, not an independent deep graph of every bound object. Binding one mutable dictionary can still expose shared mutation across tasks. Context propagation into thread/process boundaries also depends on the API used. Python asyncio TaskGroup: cancel sibling work and retain failure evidence and Python shallow and deep copies: preserve aliases deliberately explain why task-local names alone do not isolate all state.

Working program

python
import asyncio
from contextvars import ContextVar

receipt_context = ContextVar("receipt_context", default="unassigned")
async def inspect_receipt(receipt_id):
    token = receipt_context.set(receipt_id)
    try:
        await asyncio.sleep(0)
        return receipt_context.get()
    finally:
        receipt_context.reset(token)

async def inspect_batch():
    token = receipt_context.set("batch-DEL")
    try:
        print(await asyncio.gather(inspect_receipt("R-0041"), inspect_receipt("R-0042")))
        print("parent:", receipt_context.get())
    finally:
        receipt_context.reset(token)

asyncio.run(inspect_batch())
print("outside:", receipt_context.get())

Output

Output
['R-0041', 'R-0042']
parent: batch-DEL
outside: unassigned

Costs and limits

Context bindings add per-context state while referenced objects retain their own memory costs. This fixture schedules no network or external work. The scheduling yield tests binding separation rather than latency or parallel CPU execution.

Common Mistakes

  • Reset a temporary binding using the token returned by set.
  • A context-local reference can still point to a shared mutable object.

Connected lessons

Python asyncio TaskGroup: cancel sibling work and retain failure evidence, Python shallow and deep copies: preserve aliases deliberately, Python logging: include bounded context without printing sensitive payloads.

Trace the related workflow

Python asyncio.to_thread: carry context into blocking work.

python
context-variables
Storage details