testsAndMisc/docs/superpowers/evidence/brother-printer-cups-fallback-split-2026-08-16.json
Krzysztof kuhy Rudnicki 143dd9ff3d Split brother_printer CUPS fallback query out of cups_service
cups_service.py 406 -> 234. The IPP attribute queries, the CUPS
status-code mapping, find_cups_printer_name and query_usb_via_cups move
to _cups_fallback.py; cups_service keeps service control and raw USB
port status.

The seam is not the section header: test_cups_service_part2.py imports
_get_cups_economode and find_cups_printer_name together and patches
shutil once, so those two had to travel as a pair. test_cups_service.py,
the largest module, needs no edit.

usb_query.py reaches the fallback through a late import_module, so both
that string and the absolute patch target in test_usb_query.py moved
with it. Pass count is 402 before and after.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-16 17:02:42 +02:00

49 lines
3.8 KiB
JSON

{
"intent": "Bring brother_printer/cups_service.py under the 250-line cap by moving the IPP queries, status-code mapping and CUPS-based USB fallback into their own module, with no behaviour change.",
"scope": [
"python_pkg/brother_printer/_cups_fallback.py (new)",
"python_pkg/brother_printer/cups_service.py",
"python_pkg/brother_printer/cups_queue.py, usb_query.py (import path only)",
"python_pkg/brother_printer/tests/test_cups_service_part2.py, part3, part4 (MOD and import path only)",
"python_pkg/brother_printer/tests/test_usb_query.py (one absolute patch target)",
"Non-goal: no assertion changed, no test deleted, skipped or weakened"
],
"changes": [
"Moved _parse_ipp_attributes, _get_cups_ipp_status, _get_cups_economode, _map_cups_to_status_code, _cups_reasons_to_error, _port_status_to_status_code, find_cups_printer_name and query_usb_via_cups verbatim into python_pkg/brother_printer/_cups_fallback.py.",
"The seam is the whole IPP-onwards section rather than the section header at line 237: test_cups_service_part2.py imports both _get_cups_economode and find_cups_printer_name and patches shutil once, so those two had to travel together or that module would need two MOD constants.",
"_cups_fallback imports _ensure_cups_running, _get_pyusb_device_info and _query_usb_port_status_raw from cups_service, so test_cups_service_part3.py can patch all five of its targets on one module.",
"cups_service.py dropped the imports only the moved code used (re, printer_info_from_cups, run_command_text, estimate_consumable_life, USBResult, the three CUPS mapping tables and the three DERIVED_* codes) and its docstring now names the new module; 406 -> 234 lines.",
"cups_queue.py imports find_cups_printer_name from _cups_fallback, and usb_query.py's late importlib.import_module now names _cups_fallback. test_usb_query.py patches that path absolutely, so its one patch string moved with it."
],
"verification": [
{
"command": "PYTHONPATH=. python3 -m pytest python_pkg/brother_printer/tests -q",
"result": "pass",
"evidence": "402 passed before the split and 402 passed after it - identical pass count, not merely a green run."
},
{
"command": "PYTHONPATH=. python3 -c \"from python_pkg.brother_printer import _cups_fallback as q, cups_service as c, cups_queue as cq; q._ensure_cups_running; q._query_usb_port_status_raw; q.find_cups_printer_name; q.shutil; q.subprocess; c.fcntl; c.os; c.Path; c.time; cq.find_cups_printer_name\"",
"result": "pass",
"evidence": "runtime probe OK - every name the four test modules patch is still a real attribute of the module they name, so ruff's TC001 rewrite trap did not fire."
},
{
"command": "wc -l python_pkg/brother_printer/cups_service.py python_pkg/brother_printer/_cups_fallback.py",
"result": "pass",
"evidence": "234 and 209 lines, both under the 250-line cap in a single cut."
},
{
"command": "pre-commit run --files <the nine touched files>",
"result": "pass",
"evidence": "ruff, ruff format, mypy, pylint, bandit and pytest-with-coverage all pass on the touched files."
}
],
"risks": [
"usb_query.py reaches the fallback through a late importlib.import_module with the module path as a string, which no import checker validates. Covered by test_usb_query.py exercising that path, and by the pass count staying at 402 - a stale string would have raised ModuleNotFoundError there.",
"cups_queue -> _cups_fallback -> cups_service is now a three-module chain; moving anything else out of cups_service must keep that direction to avoid a cycle."
],
"rollback": [
"git revert the commit; cups_service.py returns to 406 lines and _cups_fallback.py disappears.",
"After rollback, re-run the package suite and confirm it still reports 402 passed."
]
}