FIX: Make CLI/output encoding safe on Windows consoles#2213
Merged
romanlutz merged 1 commit intoJul 17, 2026
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52d2518d-ebe5-4888-8189-6146b6503448
behnam-o
approved these changes
Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Running the scanner CLI and output sinks on a limited Windows console (for example a cp1252 or plain ASCII code page) can crash with
UnicodeEncodeErrorwhen non-ASCII text reaches stdout. Two spots are affected: the scenario run progress bar renders with Unicode block characters, andStdoutSinkcan be handed arbitrary Unicode from scenario output.This change makes both paths degrade gracefully instead of crashing:
pyrit/cli/_output.py: before emitting the progress bar, probe whether the Unicode bar encodes under the currentsys.stdout.encoding. If it does not (LookupErrororUnicodeEncodeError), fall back to an ASCII bar using#and-.pyrit/output/sink.py:StdoutSink.write_asyncnow checks whether the data is representable in the console encoding and, if not, writes it back througherrors="replace"so unencodable characters become a placeholder rather than raising. This also switches fromprinttosys.stdout.write.Both fallbacks are no-ops on UTF-8 consoles, so normal output is unchanged.
Tests and Documentation
Added focused unit tests:
test_print_scenario_run_progress_uses_ascii_for_limited_console- with a cp1252 stdout, asserts the progress bar renders the ASCII[###...---]form.test_stdout_sink_replaces_unsupported_unicode- with a cp1252 stdout, asserts an emoji plus box-drawing dash is written as a replacement placeholder rather than raising.Targeted unit runs pass:
tests/unit/cli/test_output.pyandtests/unit/output/test_sink.py(50 passed). The behavior was additionally verified end to end against a real cp1252errors="strict"stdout wrapper, confirming the pre-patchUnicodeEncodeError, the ASCII progress-bar fallback, and theerrors="replace"sink behavior, with plain ASCII output passing through untouched.JupyText note: the related scanner notebooks (
doc/scanner/1_pyrit_scan.py,doc/scanner/benchmark.py) were not executed as part of this validation because of a pre-existing local environment issue unrelated to this change (a stale~/.pyrit/.pyrit_confreferencing a removedairtinitializer prevents the backend from starting, and an ipykernel/IPython combination is incompatible with the local Python 3.14 kernel). Neither is caused by this diff.