`sys.ps1`/`sys.ps2` should be empty (or not shown) if stdin is not a tty
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 36k
- Métriques de merge des PR
- Métriques de PR en attente
Description
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.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par exécuter le reproducteur heredoc avec python3 -qi et observez les invites écrites sur stderr lorsque stdin n’est pas un TTY. Suivez la saisie interactive et la gestion des invites autour de sys.ps1 et sys.ps2 ; le travail est terminé lorsque les invites sont vides ou supprimées pour stdin qui n’est pas un TTY, tandis que le comportement normal du TTY interactif et la sortie d’erreur restent inchangés.
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
- 45/100