Fix: use DARK_GRAY for unmapped content type groups in CLI output (fixes #1243)#1317
Conversation
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.
There was a problem hiding this comment.
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.
| 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) |
There was a problem hiding this comment.
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.
|
Thanks for the review! Applied the suggestion — switched to pytest's |
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 tocolors.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:"text"and"unknown"incolor_by_group, both mapped tocolors.DARK_GRAY.colors.WHITEtocolors.DARK_GRAYso 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
test_colored_output_visible_on_light_background_terminalsinpython/tests/test_python_magika_client.py— reproduces the exact scenario from the issue: runs the CLI with--colorson a plain.txtfile (classified asgroup="text"), asserts the output containsDARK_GRAYand does not containWHITE.uv run pytest tests -m "not slow")ruff check,ruff format, andmypyall pass cleanChecklist