python-trio / python-trio/trio

Idea: TreeVar (context variables that follow stack discipline)

Open
#1,523 19 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

design discussion
Dominant language
Python
Stars
7.3k
Forks
431
Avg merge
2d 17h
Merged PRs (30d)
6

Description

A context variable is a convenient way to track something about the scope in which a task executes. Sometimes that "something" effectively constitutes a promise to child tasks that some resource remains usable. For example, trio_asyncio.open_loop() provides the asyncio loop via a contextvar, but it's not much use if the async with block has exited already.

Unfortunately, contextvars are inherited from the environment of the task spawner, not the environment of the nursery in which the task runs. That means they can't reliably provide resources to a task, because the resources might be released before the task finishes. Imagine:

async with trio.open_nursery() as nursery:
    async with trio_asyncio.open_loop() as loop:
        nursery.start_soon(some_asyncio_task)

It would be nice to have a kind of contextvar that is inherited by child tasks based on the value it had when their nursery was opened, rather than the value it had when the child task was spawned. (In theory, cancellation status could use this if it existed. In practice, we probably want to continue to special-case cancellation status because it's so fundamental.)

Implementation idea: each scoped contextvar uses an underlying regular contextvar whose value is a tuple (scoped contextvar's value, task that set it). Also, capture the contextvars context when creating a nursery (this is cheap, since contexts are meant to be shallow-copied all the time). When accessing the value of a scoped contextvar, check whether the underlying regular contextvar was set in the task we're currently in. If so, return the value from the underlying regular contextvar in the current context; otherwise, return its value in our parent nursery's captured context.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No files or tests are named. Start by tracing Trio nursery creation and contextvars handling, then compare the proposed nursery-captured inheritance semantics with existing behavior; done means a scoped context variable follows nursery stack discipline, including the shown open_loop scenario.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.