The api typecheck job is continue-on-error but still posts a failure
status that blocks merges. Three pre-existing mypy errors on dev were
inherited by every PR based on it:
1. middleware/rate_limit.py: duplicate 'name already defined' for
_public_limiter, _auth_limiter, _auth_strict_limiter (declared at
lines 111-113 and again at 124-126). The second set is redundant
because actual assignment happens inside the if/else below.
2. cache.py:43 - 'Returning Any' from .get(); the redis client's get()
return type isn't narrowed to bytes|str, so the final 'return value'
branch is Any. Wrap with str() to satisfy the declared str|None.
3. middleware/rate_limit.py:150 - 'Returning Any' from _get_client_ip.
request.headers.get() and request.client.host are typed Any; wrap
the branches with str() to match the declared str return.
Refs CAR-1335.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- tests/test_openapi.py: collapse 2 blank lines to 1 (ruff format)
- tests/conftest.py: collapse 2 blank lines to 1 (ruff format)
These format nits block lint (a hard gate). The conftest.py one was
introduced in CAR-1132 (#42) and would have blocked every subsequent PR
on dev until fixed.
Refs CAR-1335, CAR-1135.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- main.py: add docstring inside the lifespan function explaining why
dispose_engine is lazy-imported rather than top-level. The original
import path (top-level) crashed the container at import time with
'ImportError: cannot import name dispose_engine from cartsnitch_api.database'
when database.py was stale or stripped during a CI build. Lazy import
keeps the engine disposal behavior while preventing the module-load
crash.
- tests/test_openapi.py: add test_dispose_engine_importable_from_database
that asserts dispose_engine is importable and callable. This is the
exact path the deployed UAT image was failing on, captured as a
regression test so a future regression lands in CI before deploy.
Refs CAR-1135.
Co-Authored-By: Paperclip <noreply@paperclip.ing>