python / python/cpython

repl buffering conflicts with sys.stdin

未關閉
#99,751 2 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

topic-repl type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

Bug report

When running the interpreter (python -i) the REPL appears to implement its own buffering, independent of sys.stdin and its internal buffer.

Consider the following (working) example, manually entered into the REPL via the keyboard:

$ python3 -i
Python 3.11.0 (main, Oct 24 2022, 00:00:00) [GCC 12.2.1 20220819 (Red Hat 12.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print('hello', sys.stdin.readline())
world
hello world

>>>

This appears to work only because at the time I hit <enter> after the print() line, the world isn't available to read yet, and therefore the repl can't possibly consume it. If I put the whole thing into a file, and cat it in one go, however:

$ cat example.py 
import sys
print('hello', sys.stdin.readline())
world

$ cat example.py | python3 -i                                          ST 12   peer 
Python 3.11.0 (main, Oct 24 2022, 00:00:00) [GCC 12.2.1 20220819 (Red Hat 12.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> >>> hello 
>>> Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'world' is not defined
>>> >>> 

We can see that readline() returns nothing at all, because world has already been consumed by the repl, which attempts (and fails) to interpret it as the next command to be executed.

You can work around this issue by inserting even the tiniest of pauses. Consider:

$ cat example.py
import sys
print('hello', sys.stdin.readline())
$ (cat example.py; echo world) | python3 -i
Python 3.11.0 (main, Oct 24 2022, 00:00:00) [GCC 12.2.1 20220819 (Red Hat 12.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> >>> hello 
>>> Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'world' is not defined
>>> 

(ie: broken)

but:

$ (cat example.py; sleep 0.1; echo world) | python3 -i
Python 3.11.0 (main, Oct 24 2022, 00:00:00) [GCC 12.2.1 20220819 (Red Hat 12.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> >>> hello world

(ie: working).

Your environment

Stock python3-3.11.0-1.fc37.x86_64 package installed on Fedora 37.

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

python -i 直譯器進入點開始,使用報告中的命令重現該行為,並比較立即透過管線傳入的輸入與由 sleep 0.1 延遲的輸入。追蹤 REPL 相對於 sys.stdin.readline() 如何消耗輸入;完成的標準是,管線傳入的輸入不會在範例讀取它之前被 REPL 消耗,而且報告中的重現結果表現一致。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
cli
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。