Files
Eric Mey 6d6b535266 chore(review): address code-review findings
Three logical changes rolled into one commit:

1. stdlib HTTP read timeout. urlopen's `timeout=` only bounds connect,
   and CPython versions disagree on whether the resulting socket keeps
   that pinned. A half-dead Immich server that has sent headers but
   stalls on the body would hang the whole batch. Pin a read-side
   timeout on every HTTPConnection/HTTPSConnection at import so the
   bound holds across versions and reading paths. Verified with a
   stand-alone server/client pair: with the fix, a stalled body read
   fails in 0.5s with TimeoutError; without the fix, the same script
   hangs past the test timeout.

   Also distinguish `_add_to_album` ambiguity from failure: an entry
   that omits `success` is now treated the same way as an empty body
   (downgrade to `album: "unconfirmed"`), not as a ValueError. Only an
   entry that explicitly says `success: false` raises. Broadens the
   transient-error catch in `_wait_for_storage_settle` from
   (HTTPError, URLError) to OSError so socket timeouts and connection
   resets during polling do not abort the wait.

2. CI matrix now includes 3.11. tomllib is stdlib from 3.11, and the
   packaging-drift test in tests/test_packaging.py uses it. Without
   3.11 the 3.10 job importorskip-s that test, leaving drift
   detection silent at the lowest supported interpreter.

3. Test ergonomics. tests/conftest.py extracts the per-test image
   batch fixture (was duplicated across 10+ tests). README clarifies
   that retry_archive's exit code reflects `errors` entries only —
   `unconfirmed` album results exit 0, not non-zero.

Plus a User-Agent string that reports the installed package version
(via importlib.metadata) so the value cannot drift from pyproject.toml.
70 tests pass; was 62. ruff + mypy clean. Verified on Python 3.11
and 3.12 locally.
2026-09-22 15:40:28 -04:00

35 lines
1.3 KiB
Python

"""Packaging metadata checks.
The runtime dependency list exists twice -- pyproject.toml for pip, and
requirements.txt for ComfyUI Manager, which does not read pyproject. Neither
file can be dropped, so the only defence against drift is a test.
"""
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parent.parent
def _declared_requirements():
lines = ROOT.joinpath("requirements.txt").read_text().splitlines()
return [line.strip() for line in lines if line.strip() and not line.startswith("#")]
def test_requirements_matches_pyproject_dependencies():
# tomllib is stdlib from 3.11; the CI matrix covers this on 3.11/3.12/3.13.
# The 3.10 job will skip via importorskip rather than fail; that is fine —
# the packaging invariant is already enforced on every newer interpreter.
tomllib = pytest.importorskip("tomllib")
with ROOT.joinpath("pyproject.toml").open("rb") as f:
pyproject = tomllib.load(f)
assert _declared_requirements() == pyproject["project"]["dependencies"]
def test_requirements_are_unpinned_lower_bounds():
"""A custom node must not pin the host ComfyUI environment's packages."""
for requirement in _declared_requirements():
assert ">=" in requirement, requirement
assert not any(op in requirement for op in ("==", "<", "~=")), requirement