Skip to content

Fix: use DARK_GRAY for unmapped content type groups in CLI output (fixes #1243)#1317

Open
shivamtiwari3 wants to merge 2 commits intogoogle:mainfrom
shivamtiwari3:fix/use-dark-gray-for-unmapped-content-groups
Open

Fix: use DARK_GRAY for unmapped content type groups in CLI output (fixes #1243)#1317
shivamtiwari3 wants to merge 2 commits intogoogle:mainfrom
shivamtiwari3:fix/use-dark-gray-for-unmapped-content-groups

Conversation

@shivamtiwari3
Copy link

Summary

Fixes #1243.

The Python CLI's colored output was nearly invisible on light-background terminals because content type groups not explicitly listed in color_by_group (including "text", "unknown", "application", "font", "inode") all fell back to colors.WHITE (\033[1;37m — bright white), which disappears on white terminal backgrounds.


Root Cause

In magika_client.py:L312, color_by_group.get(group, colors.WHITE) was used to select the ANSI color. The dict covered 7 groups but the model has 12, so 5 groups — including the common "text" and "unknown" — silently fell back to bright white. On a light-background terminal, this produces output that looks like light gray at best and invisible at worst.


Solution

Two targeted changes in python/src/magika/cli/magika_client.py:

  1. Add explicit entries for "text" and "unknown" in color_by_group, both mapped to colors.DARK_GRAY.
  2. Change the dict fallback from colors.WHITE to colors.DARK_GRAY so any future unmapped groups also display visibly.

DARK_GRAY (\033[1;30m — bold/bright black) renders as dark gray on light terminals (clearly visible on white) and as dark gray on dark terminals (readable, appropriate for lower-confidence output). This matches the approach suggested in the issue: "Darkening the gray should solve the problem nicely, without being too hard to see on a dark background."


Testing

  • Added test_colored_output_visible_on_light_background_terminals in python/tests/test_python_magika_client.py — reproduces the exact scenario from the issue: runs the CLI with --colors on a plain .txt file (classified as group="text"), asserts the output contains DARK_GRAY and does not contain WHITE.
  • All 32 existing tests continue to pass (uv run pytest tests -m "not slow")
  • ruff check, ruff format, and mypy all pass clean

Checklist

  • Fixes the root cause (bright-white fallback replaced with dark gray)
  • New test covers the exact failing scenario from the issue
  • All existing tests pass
  • No unrelated changes
  • Code style matches project conventions (ruff + mypy clean)
  • Read CONTRIBUTING.md

Root cause: color_by_group in magika_client.py did not have entries for
"text", "unknown", "application", "font", and "inode" groups, so they
all fell back to colors.WHITE (\033[1;37m — bright white). On
light-background terminals this produces nearly invisible output.

Fix: add explicit "text" and "unknown" mappings to DARK_GRAY, and
change the dict's default fallback from colors.WHITE to colors.DARK_GRAY.
DARK_GRAY (\033[1;30m) is visible on both dark and light terminals.

Regression test added: verifies that plain-text file output uses
DARK_GRAY and not the bright-white code that breaks on white backgrounds.
@shivamtiwari3 shivamtiwari3 requested a review from reyammer as a code owner March 11, 2026 19:12
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly addresses the issue of nearly invisible CLI output on light-background terminals by changing the fallback color for unmapped content type groups to DARK_GRAY. The changes are logical, and the inclusion of a new regression test ensures the fix is robust. I have one suggestion to improve the new test's implementation for handling temporary files, making it more idiomatic and cleaner.

Comment on lines +37 to +77
def test_colored_output_visible_on_light_background_terminals() -> None:
"""Regression test for https://github.com/google/magika/issues/1243.

The fallback color for content type groups not explicitly mapped in
color_by_group must not be bright white (\033[1;37m), which is nearly
invisible on light-background terminals. DARK_GRAY (\033[1;30m) is
visible on both dark and light backgrounds.
"""
python_root_dir = Path(__file__).parent.parent
python_magika_client_path = (
python_root_dir / "src" / "magika" / "cli" / "magika_client.py"
).resolve()

# Write a plain text file — classified as group="text", which previously
# fell through to the bright-white fallback color.
with tempfile.NamedTemporaryFile(suffix=".txt", mode="w", delete=False) as tmp:
tmp.write("Hello, world!\n")
tmp_path = Path(tmp.name)

try:
result = subprocess.run(
[str(python_magika_client_path), "--colors", str(tmp_path)],
capture_output=True,
text=True,
check=True,
)
output = result.stdout
# The output must not contain the bright-white ANSI code, which is
# invisible on white/light-background terminals.
assert colors.WHITE not in output, (
f"Output used bright-white ({repr(colors.WHITE)}), which is "
"invisible on light-background terminals. Use DARK_GRAY instead."
)
# DARK_GRAY must be present so that content types in the "text" group
# (and any other unmapped group) are readable on light terminals.
assert colors.DARK_GRAY in output, (
f"Expected DARK_GRAY ({repr(colors.DARK_GRAY)}) in colored output "
"for a plain-text file, but it was not found."
)
finally:
tmp_path.unlink(missing_ok=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For cleaner and more idiomatic temporary file handling in tests, consider using pytest's built-in tmp_path fixture. It simplifies the code by automatically managing the lifecycle of temporary directories and files, removing the need for tempfile.NamedTemporaryFile with delete=False and a manual try...finally cleanup block.

def test_colored_output_visible_on_light_background_terminals(tmp_path: Path) -> None:
    """Regression test for https://github.com/google/magika/issues/1243.

    The fallback color for content type groups not explicitly mapped in
    color_by_group must not be bright white (\033[1;37m), which is nearly
    invisible on light-background terminals. DARK_GRAY (\033[1;30m) is
    visible on both dark and light backgrounds.
    """
    python_root_dir = Path(__file__).parent.parent
    python_magika_client_path = (
        python_root_dir / 'src' / 'magika' / 'cli' / 'magika_client.py'
    ).resolve()

    # Write a plain text file — classified as group='text', which previously
    # fell through to the bright-white fallback color.
    test_file = tmp_path / 'test.txt'
    test_file.write_text('Hello, world!\n')

    try:
        result = subprocess.run(
            [str(python_magika_client_path), '--colors', str(test_file)],
            capture_output=True,
            text=True,
            check=True,
        )
        output = result.stdout
        # The output must not contain the bright-white ANSI code, which is
        # invisible on white/light-background terminals.
        assert colors.WHITE not in output, (
            f'Output used bright-white ({repr(colors.WHITE)}), which is '
            'invisible on light-background terminals. Use DARK_GRAY instead.'
        )
        # DARK_GRAY must be present so that content types in the 'text' group
        # (and any other unmapped group) are readable on light terminals.
        assert colors.DARK_GRAY in output, (
            f'Expected DARK_GRAY ({repr(colors.DARK_GRAY)}) in colored output '
            'for a plain-text file, but it was not found.'
        )
    finally:
        test_file.unlink(missing_ok=True)

Replace tempfile.NamedTemporaryFile + try/finally with pytest's built-in
tmp_path fixture, which automatically manages temporary file lifecycle.
Suggested by Gemini Code Assist in PR review.
@shivamtiwari3
Copy link
Author

Thanks for the review! Applied the suggestion — switched to pytest's tmp_path fixture, which also lets us remove the try/finally cleanup block and the tempfile import entirely since tmp_path handles lifecycle automatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Light gray on white is no good

1 participant