python / python/cpython

repl buffering conflicts with sys.stdin

Ouverte
#99,751 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

topic-repl type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
36k
Métriques de merge des PR
Métriques de PR en attente

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par le point d’entrée de l’interpréteur python -i et reproduisez le comportement à l’aide des commandes du rapport, en comparant une entrée transmise immédiatement avec une entrée retardée par sleep 0.1. Suivez la manière dont la REPL consomme l’entrée par rapport à sys.stdin.readline() ; le travail est terminé lorsque l’entrée transmise n’est pas consommée par la REPL avant que l’exemple ne la lise, et que les reproductions indiquées se comportent de manière cohérente.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
cli
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.