Skip to content

conductor doctor table output dies part-written on a cp1252 console (hardcoded glyphs) #401

Description

What

conductor doctor's default table output dies on a cp1252 console, part-written.

doctor.py hardcodes three glyphs that cp1252 cannot encode:

_CHECK = "[green]✓[/green]"          # U+2713
_CROSS = "[red]✗[/red]"              # U+2717
_OPTIONAL_MARK = "○"                 # U+25CB

Verified — all three raise UnicodeEncodeError under cp1252. (_DASH, U+2014, is encodable at 0x97 and is fine.)

Why it is worse than one bad line

_render_env and _render_providers are separate console.print() calls, so stdout is left truncated mid-report rather than failing cleanly. And it lands on precisely the person least able to absorb it: someone who ran doctor because they hit #342.

Scope

#381 fixes the JSON sinks (--json is safe via ensure_ascii=True) and deliberately leaves the table path alone, because every glyph consumer would need the console threaded through it — roughly 18 call sites across _render_env, _render_providers and six _*_cell helpers, none of which currently take a console.

Suggested shape

Select glyphs once from the console's stream encoding and pass them down, falling back to ASCII (OK / X / o) when the stream cannot represent them:

def _encodable(text: str, console: Console) -> bool:
    encoding = getattr(getattr(console, "file", None), "encoding", None)
    if not encoding:
        return True
    try:
        text.encode(encoding)
    except (UnicodeEncodeError, LookupError):
        return False
    return True

Rich does not check this itself — it hands the string to the underlying file, so the error surfaces from the write, after part of the report is already out.

Repro

PYTHONIOENCODING=cp1252 conductor doctor
# exit 1, stdout ends after the Environment table

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions