Allow libraries to opt-in to context variable inheritance by new threads
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Feature or enhancement
Proposal:
Provide a mechanism for a library to declare that the state it keeps in context variables should be inherited by newly started threads, without requiring the whole application to enable the thread_inherit_context flag and without requiring the code that creates threads to cooperate.
Libraries are encouraged to store formerly global or thread-local state in contextvars.ContextVar so the state is safe for asyncio tasks and free-threaded code. An example is numpy's printoptions, which moved from a module-level global to a context variable so that with numpy.printoptions(...) is isolated between concurrently running tasks.
This migration has a thread-visibility regression on builds where sys.flags.thread_inherit_context is false (the default for GIL-enabled builds). New threads start with an empty context, so a binding made by the starting thread is not visible in the worker thread and the state silently reverts to its default:
with numpy.printoptions(precision=2):
# thread prints with default precision unless
# thread_inherit_context is enabled
threading.Thread(target=work).start()
When the state was a module-level global, worker threads always saw the current value. After moving to a context variable, they no longer do. This makes the migration a behavior change for existing threaded programs, which discourages libraries from adopting context variables at all.
The existing mechanisms are not usable by the library author:
-X thread_inherit_context=1/ PYTHON_THREAD_INHERIT_CONTEXT is process-wide and controlled by the application or end user, not by the library whose state is affected. A library cannot require every application embedding it to change interpreter flags, and enabling whole-context inheritance may be undesirable for unrelated reasons.threading.Thread(context=...)requires the code constructing the thread to pass the context. Threads are typically created by application code, frameworks, or thread pools that know nothing about the library's context variables.
What is missing is a middle ground between "threads inherit nothing" and "threads inherit everything": a way for a library to opt its own state into inheritance across threading.Thread.start(), on a per-library (or per-variable) basis, regardless of the process-wide flag. This would let libraries convert global state to context-local state without regressing thread behavior, and would ease the eventual transition to thread_inherit_context defaulting to true, since libraries opting in today would see no behavior change when the default flips.
Explicitly supplied contexts (Thread(context=...)) should continue to behave as they do now.
Has this already been discussed elsewhere?
I have already discussed this feature proposal on Discourse
Links to previous discussion of this feature:
Linked PRs
- gh-154564
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
该 issue 提到了 threading.Thread.start()、Thread(context=...) 和 contextvars.ContextVar;请先阅读这些入口点以及链接的 PR gh-154564。完成的标准是:库可以选择将 context-variable 状态纳入新启动线程的继承,同时 Thread(context=...) 的显式行为和进程范围标志的语义保持不变。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- operating-systems
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 25/100