diff --git a/loguru/_colorama.py b/loguru/_colorama.py index b380536c..220ddd89 100644 --- a/loguru/_colorama.py +++ b/loguru/_colorama.py @@ -7,9 +7,16 @@ def should_colorize(stream): if stream is None: return False - if "NO_COLOR" in os.environ: + # Per the spec (https://no-color.org/), this needs to check for a + # non-empty string, not just presence of the variable: + if os.getenv("NO_COLOR"): return False + # Per the spec (https://force-color.org/), this needs to check for a + # non-empty string, not just presence of the variable: + if os.getenv("FORCE_COLOR"): + return True + if getattr(builtins, "__IPYTHON__", False) and (stream is sys.stdout or stream is sys.stderr): try: import ipykernel diff --git a/tests/test_colorama.py b/tests/test_colorama.py index ab659e09..1aea8e5a 100644 --- a/tests/test_colorama.py +++ b/tests/test_colorama.py @@ -154,19 +154,49 @@ def test_dumb_term_not_colored(monkeypatch, patched, expected): @pytest.mark.parametrize( - ("patched", "expected"), + ("patched", "no_color", "expected"), [ - ("__stdout__", False), - ("__stderr__", False), - ("stdout", False), - ("stderr", False), - ("", False), + ("__stdout__", "1", False), + ("__stderr__", "1", False), + ("stdout", "1", False), + ("stderr", "1", False), + ("", "1", False), + # An empty value for NO_COLOR should not be applied: + ("__stdout__", "", True), + ("__stderr__", "", True), + ("stdout", "", True), + ("stderr", "", True), + ("", "", True), ], ) -def test_honor_no_color_standard(monkeypatch, patched, expected): +def test_honor_no_color_standard(monkeypatch, patched, no_color, expected): stream = StreamIsattyTrue() with monkeypatch.context() as context: - context.setitem(os.environ, "NO_COLOR", "1") + context.setitem(os.environ, "NO_COLOR", no_color) + context.setattr(sys, patched, stream, raising=False) + assert should_colorize(stream) is expected + + +@pytest.mark.parametrize( + ("patched", "force_color", "expected"), + [ + ("__stdout__", "1", True), + ("__stderr__", "1", True), + ("stdout", "1", True), + ("stderr", "1", True), + ("", "1", True), + # An empty value for FORCE_COLOR should not be applied: + ("__stdout__", "", False), + ("__stderr__", "", False), + ("stdout", "", False), + ("stderr", "", False), + ("", "", False), + ], +) +def test_honor_force_color_standard(monkeypatch, patched, force_color, expected): + stream = StreamIsattyFalse() + with monkeypatch.context() as context: + context.setitem(os.environ, "FORCE_COLOR", force_color) context.setattr(sys, patched, stream, raising=False) assert should_colorize(stream) is expected