python / python/cpython

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

未關閉
#93,139 2 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

stdlib type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

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.

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

首先使用 python3 -qi 執行 heredoc 重現程式,並觀察 stdin 不是 TTY 時寫入 stderr 的提示字元。追蹤 sys.ps1sys.ps2 周圍的互動式輸入與提示字元處理;當對於非 TTY stdin,提示字元為空或受到抑制,同時正常的互動式 TTY 行為和錯誤輸出維持不變時,即表示完成。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
cli
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。