Builtin input does not always correctly handle errors from `PyOS_Readline`
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Assertion failure sending SIGINT while calling input
import os, signal, threading
send = threading.Event()
def interrupter():
while True:
send.wait()
os.kill(os.getpid(), signal.SIGINT)
threading.Thread(target=interrupter).start()
send.set()
while True:
try:
input(">")
except KeyboardInterrupt:
pass
Note, this is a modified version of the example code in #112585.
Python (tested v3.12.10, v3.13.3, v3.14.0b1, and current HEAD), built with assertions enabled:
~/src/cpython/ $ ./python crash.py
>>>>>>>>>>>python: Objects/call.c:342: _PyObject_Call: Assertion `!_PyErr_Occurred(tstate)' failed.
Aborted (core dumped)
IIUC the issue is builtin_input_impl in Python/bltinmodule.c calls PyOS_Readline but assumes it cannot set an exception:
s = PyOS_Readline(stdin, stdout, promptstr);
if (s == NULL) {
PyErr_CheckSignals();
if (!PyErr_Occurred())
PyErr_SetNone(PyExc_KeyboardInterrupt);
If PyOS_Readline sets an exception (e.g. as in this case by running an interrupt signal handler itself), as opposed to being interrupted by a signal and returning NULL without setting the exception, and another signal with a handler is pending when PyErr_CheckSignals() is called, the handler will be called with the prior exception already set, and hence the assertion fails.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
No response
Linked PRs
- gh-134645
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 Python/bltinmodule.c 中的 builtin_input_impl 开始,使用提供的信号和输入示例重现该断言。跟踪 PyOS_Readline 和 PyErr_CheckSignals 如何处理已有的异常;完成的标准是重现过程不再因 _PyObject_Call 断言而中止,并保留预期的中断行为。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- operating-systems
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 35/100