From python-engineering
Provides patterns for Python cross-platform script compatibility on Windows, Linux, macOS across CLI, TUI (Rich/Textual), GUI; fixes Unicode/encoding, Rich/Typer output breaks, paths, terminal detection, console colors.
npx claudepluginhub jamie-bitflight/claude_skills --plugin python-engineeringThis skill uses the workspace's default tool permissions.
Verified patterns for writing Python scripts that behave correctly on Windows, Linux, and macOS across CLI, TUI, and GUI contexts.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Verified patterns for writing Python scripts that behave correctly on Windows, Linux, and macOS across CLI, TUI, and GUI contexts.
Problem: Windows defaults stdout/stderr to a legacy code page (cp1252, cp437). Rich and Typer use Unicode characters (box-drawing, spinners, emoji) that these encodings cannot represent, causing UnicodeEncodeError at runtime.
Solution: Reconfigure streams before importing Rich or Typer.
import sys
from io import TextIOWrapper
# Ensure UTF-8 output on Windows (cp1252 default cannot encode emoji/spinner chars).
# reconfigure() is available on Python 3.7+ when stdout is a TextIOWrapper.
if isinstance(sys.stdout, TextIOWrapper):
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
if isinstance(sys.stderr, TextIOWrapper):
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
# Rich/Typer imports come AFTER the reconfigure block
import typer
from rich.console import Console
Placement rule: Immediately after stdlib imports, before any third-party imports. Rich inspects stdout encoding at import time.
errors="replace" substitutes unencodable characters with ? instead of raising. Prefer this over errors="strict" for CLI tools where a crash is worse than a degraded character.
isinstance guard skips reconfigure when stdout is not a TextIOWrapper (e.g. redirected to BytesIO in tests, or already a custom wrapper). Safe to include unconditionally.
Rich Console variant: When targeting legacy Windows consoles (cmd.exe without Windows Terminal), also pass legacy_windows=False to force ANSI escape sequences instead of the Windows Console API:
console = Console(legacy_windows=False)
Why not env vars? PYTHONUTF8=1 and PYTHONIOENCODING=utf-8 require the caller to set them before the process starts — not self-contained in the script. The reconfigure() pattern is fully portable with no external configuration required.
Also applies to: pathlib.Path.write_text(), open(), and any file I/O that inherits the default encoding. Always pass encoding="utf-8" explicitly to file write calls on Windows:
path.write_text(content, encoding="utf-8")
open(path, "w", encoding="utf-8")