Fix issues with CliRunner's echo_stdin #1820
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #1101 and some related issues with
CliRunner(echo_stdin=True)
.As raised in #1101, with Python 2 any prompted input appears twice in the output recorded by
CliRunner
when usingecho_stdin=True
. It appears to work with Python 3 becauseEchoingStdin
does not always echo. For example, usinginput
instead ofclick.prompt
:Expected output:
Actual output:
Environment: Click 7.1.2, Python 3.7.7
Here the problem was that
TextIOWrapper
tries to callread1
on the underlying input stream, which wasn't being overridden inEchoingStdin
. After adding an echoingread1
, both Python 2 and Python 3 double-echo withclick.prompt
.I've modified
visible_input
not to echo whenecho_stdin=True
. To get consistent behaviour for hidden prompts (which should not echo even ifecho_stdin=True
) I also added a way to temporarily turn off echoing insidehidden_input
. This is also used in_getchar
if it gets passedecho=False
.Finally, there was one more subtle problem in Python 3.
TextIOWrapper
provides a buffered stream that reads a large chunk from the input before parsing out individual lines. When the underlying input stream isEchoingStdin
, this causes all input (up to the chunk size) to be echoed at once. Here's another example:Expected output:
Actual output:
Environment: commit
21cde2f
(after the previously mentioned issues are fixed), Python 3.7.7The only solution I found for this was to set the
_CHUNK_SIZE
attribute ofTextIOWrapper
, which is not documented (I found it here) and I guess that means it might not be compatible with all Python implementations. It would be great if someone knows a cleaner approach, otherwise I hope it's okay to contribute something like this.Checklist:
CHANGES.rst
summarizing the change and linking to the issue... versionchanged::
entries in any relevant code docs. (n/a)pre-commit
hooks and fix any issues.pytest
andtox
, no tests failed.