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
CliRunnerwhen usingecho_stdin=True. It appears to work with Python 3 becauseEchoingStdindoes not always echo. For example, usinginputinstead ofclick.prompt:Expected output:
Actual output:
Environment: Click 7.1.2, Python 3.7.7
Here the problem was that
TextIOWrappertries to callread1on 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_inputnot 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_getcharif it gets passedecho=False.Finally, there was one more subtle problem in Python 3.
TextIOWrapperprovides 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_SIZEattribute 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.rstsummarizing the change and linking to the issue... versionchanged::entries in any relevant code docs. (n/a)pre-commithooks and fix any issues.pytestandtox, no tests failed.