python / python/cpython

repl buffering conflicts with sys.stdin

Đang mở
#99,751 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

topic-repl type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
36k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

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.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với điểm vào của trình thông dịch python -i và tái hiện hành vi bằng các lệnh trong báo cáo, so sánh đầu vào được chuyển qua pipe ngay lập tức với đầu vào bị trì hoãn bởi sleep 0.1. Theo dõi cách REPL tiêu thụ đầu vào so với sys.stdin.readline(); được xem là hoàn tất khi đầu vào được chuyển qua pipe không bị REPL tiêu thụ trước khi ví dụ đọc nó, và các lần tái hiện được báo cáo đều hoạt động nhất quán.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
cli
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.