rich
rich copied to clipboard
[BUG] console.input always prints to stdout regardless of stderr setting
Describe the bug
I have an application that is intended be run as part of a pipeline, e.g. myapp | sendmail
, but is very interactive, with menus, text inputs, etc. I want to use Rich to make it nicer, but I am stuck getting console.input
to work without printing anything to stdout.
from rich.console import Console
console = Console(stderr=True)
console.print('Hello world')
console.input('Input: ')
$ myapp > /dev/null
Hello world
(hangs here waiting for input, but prompt is hidden)
The problem seems to be that Console.input()
just calls the built-in input()
function, which is known to behave incorrectly (bpo #1927). Without Rich, it's simple enough to work around that behavior by printing the prompt directly to sys.stderr
and passing an empty string to input()
. Indeed, I could do the same with Rich and avoid using Console.input()
, but this means I cannot use things like Prompt.ask
, etc.
Console.input()
does have a couple of code paths where it respects self.file
. I thought calling console.input(..., stream=sys.stdin)
might work, but it does not because Console.input
does not call self.file.flush()
after printing the prompt.
I think at the very least, Console.input()
should call self.file.flush()
after writing the prompt. I don't think this would hurt anything, and it would allow Rich to keep its current behavior of just calling input()
in the default case. If people want to avoid printing anything to stdout, they can work around the behavior by passing stream=sys.stdin
. On the other hand, I am not sure what advantage using input()
provides, so it may be a better idea to remove that code path and make the default behavior be to print the prompt directly and then read a line from stdin.
@AdmiralNemo I am unable to reproduce the issue on my side, is the issue fixed?
@spotted-cat no, the issue is not fixed. The code listed in the original description still behaves exactly the same on rich-11.0.0. The prompt text from console.input
is always written to standard output.
@AdmiralNemo currently the code for Console.input()
passes the prompt argument to Console.print()
which is captured to give the resulting raw string, This raw string eventually is passed as the prompt argument to the inbuilt input
function. One way to rectify your problem would be to check for the stderr flag and if it is set then to directly print the text using Console.print()
and avoid passing any promp arguments to the inbuilt input()
function? Are there any problems with this approach ??
Indeed, I could do the same with Rich and avoid using
Console.input()
, but this means I cannot use things likePrompt.ask
, etc.