Skip to content

Add option --color=<always|never|auto>#8135

Closed
cjolowicz wants to merge 12 commits intopypa:masterfrom
cjolowicz:color-option
Closed

Add option --color=<always|never|auto>#8135
cjolowicz wants to merge 12 commits intopypa:masterfrom
cjolowicz:color-option

Conversation

@cjolowicz
Copy link
Copy Markdown
Contributor

@cjolowicz cjolowicz commented Apr 25, 2020

Add a new option --color=WHEN. WHEN can be always, auto, or never:

  • always: Force color output
  • auto: Enable color if output is a tty (default behavior)
  • never: Do not color output.

With this change, the existing option --no-color becomes a shorthand for --color=never.

Closes #8132

Having a way to force color output is useful because some environments don't provide a tty, while colors would still improve readability. For example, this is currently the case with GitHub Actions.

@cjolowicz
Copy link
Copy Markdown
Contributor Author

cjolowicz commented Apr 25, 2020

The test for --color=always fails on Windows. And it makes sense: The test looks for the ANSI color sequence, but colorama strips it from the output and converts it into win32 calls.

Update: This was resolved by the commits below. The commits add unit tests for ColorizedStreamHandler, checking whether colorama.win32.SetConsoleTextAttribute is called for different settings of the color parameter. These tests run only on Windows, when colorama is installed and output is connected to a terminal.

On Windows, colorama strips ANSI color sequences from the output and
converts them into win32 calls. So the test case does not find them in
pip's output.

We might be able to monkeypatch our way around this, but the added value
is doubtful. If the color sequences are emitted as expected on the other
platforms, then colorama should take care of the rest.
Comment thread tests/functional/test_color.py Outdated
Claudio Jolowicz added 4 commits April 25, 2020 21:47
On Windows, colorama translates ANSI color sequences into calls to
SetConsoleTextAttribute[1]. We can check if pip uses colored output on
Windows by monkey-patching `colorama.win32.SetConsoleTextAttribute`
with pretend's call recorder.

Note that this test relies on an internal interface of colorama. While
SetConsoleTextAttribute itself is part of the public win32 API, how
colorama encapsulates this function is an implementation detail.

[1]: https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute
Monkey-patching around the win32 call cannot work because the functional
tests run pip as a subprocess. And anyway, this is an implementation
detail of colorama.

Instead, simply assert that the ANSI sequence is never present on
Windows.
These tests check if SetConsoleTextAttribute is called on Windows for
various settings of the `color` parameter to ColorizedStreamHandler.
This is achieved by monkey-patching colorama.win32. Note that this
module is an internal interface, and may change without notice.

The tests disable pytest's output capturing. Colorama checks if either
STDOUT or STDERR are a console, using GetConsoleScreenBufferInfo. With
pytest's output capturing enabled, this function fails with
ERROR_INVALID_HANDLE. A log record with an empty message is used for
testing, to avoid garbage in the test runner output.
Passing color="always" won't have an effect on Windows if the output is
not a terminal. Color output on Windows relies on the win32 console
interface, and that does not apply to pipes and the like.

Colorama checks if the output is a console using
GetConsoleScreenBufferInfo with STDOUT and STDERR handles. If this check
fails, it will simply strip color sequences from the output.

with capsys.disabled():
if not win32.winapi_test():
pytest.skip("output is not connected to a terminal")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to not skip a test in the middle of itself? Maybe just return or something?
I may be wrong on this 😄

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO it might be a better idea to move the check out as a decorator, that'd be easier to understand.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there is a skipif(colorma is None)
You can add/replace in this check

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is that the check needs to run with output capturing disabled (capsys.disabled) 😳 I think it’s clearer this way, but let me know if I missing something

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I guess its okay

@pradyunsg pradyunsg added type: enhancement Improvements to functionality state: needs eyes Needs a maintainer/triager to take a closer look labels Apr 27, 2020
@BrownTruck
Copy link
Copy Markdown
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Sep 4, 2020
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Sep 12, 2020
@BrownTruck
Copy link
Copy Markdown
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Feb 4, 2021
@pradyunsg
Copy link
Copy Markdown
Member

Closing as this is significantly out of date, and has merge conflicts. Please do feel free to resubmit an updated PR for this! ^>^

Thanks for filing this PR @cjolowicz! :)

@pradyunsg pradyunsg closed this Mar 5, 2021
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Oct 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

needs rebase or merge PR has conflicts with current master state: needs eyes Needs a maintainer/triager to take a closer look type: enhancement Improvements to functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option to force color output

6 participants