{"record":{"id":"302e8f2ad611ef24","repo":"Hmbown/CodeWhale","slug":"braille-mark-py-requires-pillow-pip-install-pillow","errorCode":null,"errorMessage":"braille-mark.py requires pillow (`pip install pillow`)","messagePattern":"braille-mark\\.py requires pillow \\(`pip install pillow`\\)","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"scripts/brand/braille-mark.py","lineNumber":36,"sourceCode":"  resized.\n\n    scripts/brand/braille-mark.py                 # print + Rust consts\n    scripts/brand/braille-mark.py --png crates/tui/assets/mark-96.png --px 96\n\nRequires `pillow` (`pip install pillow`). No other dependencies.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport collections\nimport pathlib\nimport sys\n\ntry:\n    from PIL import Image\nexcept ImportError:\n    raise SystemExit(\"braille-mark.py requires pillow (`pip install pillow`)\")\n\nROOT = pathlib.Path(__file__).resolve().parents[2]\nRASTER = ROOT / \"brand\" / \"codewhalemarkfinal.png\"\n\n# Search bands as fractions of the sheet, so the boxes track the layout\n# rather than absolute pixels. The app-icon caption (\"APP ICON\", navy text)\n# sits above the icon band; the band starts below it.\nHERO_BAND = (0.0, 1.0, 0.0, 0.52)  # x0, x1, y0, y1\nICON_BAND = (0.65, 1.0, 0.55, 0.78)\nHERO_MARGIN = 12\nICON_PAD = 10\n# Sheet background (and the icon's drop shadow, darkest ~211) keys out;\n# founder navy (~15,33,65) never approaches this.\nBG_CUTOFF = 200\n# Braille dot bit for (dot_row, dot_col) inside one cell — U+2800 layout:\n# dots 1,2,3 are column 0 rows 0..2 (bits 0..2), dots 4,5,6 column 1 rows\n# 0..2 (bits 3..5), dots 7,8 are row 3 (bits 6,7).\nDOT_BITS = {","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/brand/braille-mark.py#L18-L54","documentation":"braille-mark.py imports PIL (Pillow) at module top; if Pillow is not installed, the ImportError is converted into this SystemExit message instead of a traceback. The script cannot manipulate the brand raster without Pillow.","triggerScenarios":"Running `python scripts/brand/braille-mark.py` in an environment where the `pillow` package is not installed for the active interpreter (harness.py-equivalent: scripts/brand/braille-mark.py:26-29 try/except around `from PIL import Image`).","commonSituations":"Fresh machine/CI container without dev dependencies; running with a different Python (system vs venv) that lacks Pillow; forgetting `pip install pillow` after cloning.","solutions":["Install Pillow for the current interpreter: `pip install pillow`","If using a venv, activate it first (`source .venv/bin/activate`) then install","Verify with `python -c \"import PIL; print(PIL.__version__)\"` that the same interpreter running the script has Pillow","On some distros install via package manager (e.g. `apt install python3-pil`) if pip is restricted"],"exampleFix":"# before\n$ python scripts/brand/braille-mark.py\nbraille-mark.py requires pillow (`pip install pillow`)\n# after\n$ pip install pillow\n$ python scripts/brand/braille-mark.py","handlingStrategy":"validation","validationCode":"import importlib.util\nif importlib.util.find_spec(\"PIL\") is None:\n    raise SystemExit(\"install pillow first: pip install pillow\")","typeGuard":null,"tryCatchPattern":"try:\n    run_braille_mark()\nexcept SystemExit as e:\n    if \"pillow\" in str(e):\n        subprocess.run([sys.executable, \"-m\", \"pip\", \"install\", \"pillow\"], check=True)\n        run_braille_mark()","preventionTips":["Install dev dependencies from the repo's requirements/venv setup before running scripts","Run scripts with the same interpreter you installed packages into","Verify `python -c \"import PIL\"` passes before scripted/CI runs","Use a project venv so dependencies are consistent"],"tags":["python","dependency","pillow","branding-script"],"backgroundTag":"missing-dependency","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}