python / python/cpython

`sys.ps1`/`sys.ps2` should be empty (or not shown) if stdin is not a tty

Aperta
#93,139 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

stdlib type-bug
Lingua principale
Python
Stelle
77.2k
Fork
36k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Bug report

This straddles the line between bug report and feature request.

I've searched for related issues or PRs but I wasn't able to find anything directly related. I'm sorry if this has been raised and discussed before.

Normally, if stdin is not a TTY, then python3 tries to read a script from stdin, terminating with EOF, and then runs the script. This effectively means that the script itself can't read more stdin, because EOF was already sent. A way to work around this is to use python3 -i, which then causes the interpreter to behave more like the POSIX shell, evaluating commands as it receives them.

The commandline parameter -i is documented:

When a script is passed as first argument or the -c option is used, enter interactive mode after executing the script or the command.

The scenario that python3 -i may be run without other flags isn't mentioned, but it works.

In particular, this mechanism gives me a really nice way to connect to a host with ssh, inject a script (via stdin), and then run it and interact with it. I could do the same with an extremely large -c parameter, but I'd prefer not to spam the output of ps with a gigantic script, if possible[^1].

This is all already working wonderfully. There is one strange issue, though: possibly as a side effect of #46221, on the stderr I get a whole lot of output looking like:

>>> >>> >>> >>> >>> >>> >>> >>> ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... >>> >>> 

This is, of course sys.ps1 and sys.ps2 being displayed for each line in my script. First a bunch of imports (ps1), then a block defining a class (sys.ps2), then the lines to instantiate and execute a method in that class (more sys.ps1).

I don't want to simply redirect stderr to /dev/null because my script (or the Python interpreter, in case of exceptions) could produce error output and I'd like to receive it.

There are a few other ways that I could hack around this. Something ugly like:

python3 -ic '"cockpit-bridge"; __import__('sys').ps1=""'

would do the trick (and is probably what I'll do for now), but it would be nice if this wasn't necessary.

So the ask is simple: in the case that stdin is not a tty, then sys.ps1 and sys.ps2 should either be set to empty, or not shown.

I tested a couple of POSIX shells (bash, dash) for comparison and each of them seems to do both. Specifically, when reading from a non-tty, $PS1 is unset, and is also ignored, even if I do set it to something.

Here's a simple reproducer:

sh$ python3 -qi <<EOF
print('x')
print('y')
print('z')
EOF
>>> x
>>> y
>>> z
>>> 

You can see that the prompts are going on stderr by redirecting:

bash-5.1$ python3 -qi 2>/dev/null <<EOF
> print('x')
> print('y')
> print('z')
> EOF
x
y
z

The output I'd like to see looks like:

# NB: This is not currently possible
sh$ python3 -qi <<EOF
print('x')
print('y')
print('z')
EOF
x
y
z

Your environment

Python 3.10.3 (main, Mar 18 2022, 00:00:00) [GCC 12.0.1 20220308 (Red Hat 12.0.1-0)] on linux

aka python3-3.10.3-1.fc36.x86_64.

[^1]: indeed, I intend to (ab)use -c to display the name of the script, using an (ignored) string literal like so:

`ssh somehost python3 -ic '"cockpit-bridge"'`

Using `-c` like this also means that the interactive banner gets suppressed, which means that I don't need to specify `-q` to do that.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia eseguendo il riproduttore heredoc con python3 -qi e osserva i prompt scritti su stderr mentre stdin non è un TTY. Traccia l’input interattivo e la gestione dei prompt attorno a sys.ps1 e sys.ps2; il lavoro è completato quando i prompt sono vuoti o soppressi per stdin che non è un TTY, mentre il normale comportamento del TTY interattivo e l’output degli errori rimangono intatti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
cli
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.