`sys.ps1`/`sys.ps2` should be empty (or not shown) if stdin is not a tty
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 36k
- Ø Merge
- 1 T. 9 Std.
- Gemergte PRs (30 T.)
- 558
Beschreibung
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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, den Heredoc-Reproducer mit python3 -qi auszuführen, und beobachte die auf stderr geschriebenen Eingabeaufforderungen, während stdin kein TTY ist. Verfolge die interaktive Eingabe und die Eingabeaufforderungsbehandlung rund um sys.ps1 und sys.ps2; abgeschlossen ist die Arbeit, wenn Eingabeaufforderungen für nicht-TTY-stdin leer sind oder unterdrückt werden, während das normale interaktive TTY-Verhalten und die Fehlerausgabe intakt bleiben.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- cli
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 45/100