Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NO_COLOR and FORCE_COLOR #7466

Merged
merged 7 commits into from
Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/7464.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added support for ``NO_COLOR`` and ``FORCE_COLOR`` environment variables to control colored output.

For more information, see `the docs <https://docs.pytest.org/en/stable/reference.html#environment-variables>`__.
Copy link
Contributor

Choose a reason for hiding this comment

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

This could/should use an internal reference (Python uses using-on-envvars).
In general (internal) documentation links should not go through external resources/protocols.

Copy link
Member

Choose a reason for hiding this comment

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

True, that escaped my mind, thanks. 👍

Copy link
Member

Choose a reason for hiding this comment

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

Done: #7474

Thanks again

29 changes: 23 additions & 6 deletions doc/en/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -988,10 +988,20 @@ Environment variables that can be used to change pytest's behavior.
This contains a command-line (parsed by the py:mod:`shlex` module) that will be **prepended** to the command line given
by the user, see :ref:`adding default options` for more information.

.. envvar:: PYTEST_CURRENT_TEST

This is not meant to be set by users, but is set by pytest internally with the name of the current test so other
processes can inspect it, see :ref:`pytest current test env` for more information.

.. envvar:: PYTEST_DEBUG

When set, pytest will print tracing and debug information.

.. envvar:: PYTEST_DISABLE_PLUGIN_AUTOLOAD

When set, disables plugin auto-loading through setuptools entrypoints. Only explicitly specified plugins will be
loaded.

.. envvar:: PYTEST_PLUGINS

Contains comma-separated list of modules that should be loaded as plugins:
Expand All @@ -1000,15 +1010,22 @@ Contains comma-separated list of modules that should be loaded as plugins:

export PYTEST_PLUGINS=mymodule.plugin,xdist

.. envvar:: PYTEST_DISABLE_PLUGIN_AUTOLOAD
.. envvar:: PY_COLORS

When set, disables plugin auto-loading through setuptools entrypoints. Only explicitly specified plugins will be
loaded.
When set to ``1``, pytest will use color in terminal output.
When set to ``0``, pytest will not use color.
``PY_COLORS`` takes precedence over ``NO_COLOR`` and ``FORCE_COLOR``.

.. envvar:: PYTEST_CURRENT_TEST
.. envvar:: NO_COLOR

This is not meant to be set by users, but is set by pytest internally with the name of the current test so other
processes can inspect it, see :ref:`pytest current test env` for more information.
When set (regardless of value), pytest will not use color in terminal output.
``PY_COLORS`` takes precedence over ``NO_COLOR``, which takes precedence over ``FORCE_COLOR``.
See `no-color.org <https://no-color.org/>`__ for other libraries supporting this community standard.

.. envvar:: FORCE_COLOR

When set (regardless of value), pytest will use color in terminal output.
``PY_COLORS`` and ``NO_COLOR`` take precedence over ``FORCE_COLOR``.

Exceptions
----------
Expand Down
9 changes: 5 additions & 4 deletions src/_pytest/_io/terminalwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ def should_do_markup(file: TextIO) -> bool:
return True
if os.environ.get("PY_COLORS") == "0":
return False
if "NO_COLOR" in os.environ:
return False
if "FORCE_COLOR" in os.environ:
return True
return (
hasattr(file, "isatty")
and file.isatty()
and os.environ.get("TERM") != "dumb"
and not (sys.platform.startswith("java") and os._name == "nt")
hasattr(file, "isatty") and file.isatty() and os.environ.get("TERM") != "dumb"
)


Expand Down
34 changes: 30 additions & 4 deletions testing/io/test_terminalwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,7 @@ def test_attr_hasmarkup() -> None:
assert "\x1b[0m" in s


def test_should_do_markup_PY_COLORS_eq_1(monkeypatch: MonkeyPatch) -> None:
monkeypatch.setitem(os.environ, "PY_COLORS", "1")
def assert_color_set():
file = io.StringIO()
tw = terminalwriter.TerminalWriter(file)
assert tw.hasmarkup
Expand All @@ -166,8 +165,7 @@ def test_should_do_markup_PY_COLORS_eq_1(monkeypatch: MonkeyPatch) -> None:
assert "\x1b[0m" in s


def test_should_do_markup_PY_COLORS_eq_0(monkeypatch: MonkeyPatch) -> None:
monkeypatch.setitem(os.environ, "PY_COLORS", "0")
def assert_color_not_set():
f = io.StringIO()
f.isatty = lambda: True # type: ignore
tw = terminalwriter.TerminalWriter(file=f)
Expand All @@ -177,6 +175,34 @@ def test_should_do_markup_PY_COLORS_eq_0(monkeypatch: MonkeyPatch) -> None:
assert s == "hello\n"


def test_should_do_markup_PY_COLORS_eq_1(monkeypatch: MonkeyPatch) -> None:
monkeypatch.setitem(os.environ, "PY_COLORS", "1")
assert_color_set()


def test_should_not_do_markup_PY_COLORS_eq_0(monkeypatch: MonkeyPatch) -> None:
monkeypatch.setitem(os.environ, "PY_COLORS", "0")
assert_color_not_set()


def test_should_not_do_markup_NO_COLOR(monkeypatch: MonkeyPatch) -> None:
monkeypatch.setitem(os.environ, "NO_COLOR", "1")
assert_color_not_set()


def test_should_do_markup_FORCE_COLOR(monkeypatch: MonkeyPatch) -> None:
monkeypatch.setitem(os.environ, "FORCE_COLOR", "1")
assert_color_set()


def test_should_not_do_markup_NO_COLOR_and_FORCE_COLOR(
monkeypatch: MonkeyPatch,
) -> None:
monkeypatch.setitem(os.environ, "NO_COLOR", "1")
monkeypatch.setitem(os.environ, "FORCE_COLOR", "1")
assert_color_not_set()


class TestTerminalWriterLineWidth:
def test_init(self) -> None:
tw = terminalwriter.TerminalWriter()
Expand Down