You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: planning/deferred-work.md
+1-6Lines changed: 1 addition & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,15 +4,12 @@ Items raised in reviews that are real but not actionable now.
4
4
5
5
## Deferred from: retrospective review of stories 1-1 through 1-5 (2026-05-31)
6
6
7
-
-**`PydanticDecoder.decode``TypeError` fallback is unreachable through normal usage** — the `except TypeError` branch only triggers when `_get_adapter(model)` raises during `lru_cache` lookup, which requires `model` to be unhashable; every concrete `type[T]` is hashable. The branch is now deliberately exercised via mock at `tests/test_decoders_pydantic.py:141-156`, so the contract is pinned even though no production caller hits it. (`src/httpware/decoders/pydantic.py:22-26`)
8
7
-**`_get_adapter``lru_cache` is module-global, not per-decoder instance** — keyed by `model` only; two `PydanticDecoder()` instances with different configurations (none today) would share adapters, and the cache survives across tests unless explicitly cleared. Revisit if/when a configurable `PydanticDecoder(mode=..., strict=...)` lands. (`src/httpware/decoders/pydantic.py:12-14`)
9
8
-**`extensions=dict(request.extensions)` forwards opaque payloads to httpx2 verbatim** — `httpx2` interprets specific keys (e.g. `timeout`, `sni_hostname`); a typo or unknown key silently bypasses our timeout/limits config. The seam now has a real user: `AsyncClient._build_request` writes `extensions["timeout"]` (`src/httpware/client.py:140-142`). Epic 3 timeout middleware will own the extensions contract; introducing an allowlist now risks blocking legitimate forward-compat uses. (`src/httpware/transports/httpx2.py:121`)
10
-
-**`Response.json()` raises raw `JSONDecodeError` and ignores declared charset** — `json.loads(self.content)` propagates `json.JSONDecodeError` to callers and ignores any declared charset (`text` honors it); inconsistent with `_try_decode_json` in the transport which never raises. `AsyncClient` doesn't call `.json()` (it goes through `decoder.decode`), but end users do. Two-line fix; bundle with the next response-API touch. (`src/httpware/response.py:50-52`)
11
9
12
10
## Deferred from: code review of story-1-5 (2026-05-14)
13
11
14
12
-**Empty/malformed payload tests** — `b""`, `b"null"`, `b"{}"`, invalid UTF-8: current pydantic-core behavior is correct but unpinned; a future pydantic upgrade could change error types undetected. (`tests/test_decoders_pydantic.py`)
15
-
-**`PLR2004` per-file-ignores** — `# noqa: PLR2004` repeated 5× in this test file; idiomatic fix is `tool.ruff.lint.per-file-ignores` for `tests/*`. Project-wide lint-config tidy. (`tests/test_decoders_pydantic.py:63,67,83,107,153`)
16
13
17
14
## Deferred from: code review of story-1-4 (2026-05-14)
18
15
@@ -41,7 +38,5 @@ Items raised in reviews that are real but not actionable now.
41
38
42
39
## Deferred from: code review of story-1-1 (2026-05-13)
43
40
44
-
-**`just publish` lacks env-var validation** — recipe assumes `GITHUB_REF_NAME` and `PYPI_TOKEN` are set; running locally could corrupt the version. Add `test -n "$GITHUB_REF_NAME"` guard before release work. (`Justfile:25-29`)
45
-
-**`uv_build>=0.11,<0.12` narrow window** — single-minor band will expire as soon as uv_build 0.12 ships; bump when that happens. (`pyproject.toml:49`)
46
41
-**Unpinned `ruff`/`ty` with `select=["ALL"]`** — any new ruff release adds rules and can break CI overnight. Pin major versions or pin specific rules when a regression occurs. (`pyproject.toml``[dependency-groups] lint`, `[tool.ruff.lint] select`)
47
-
-**No `[test]` extra; CI installs all extras** — `just install` runs `uv sync --all-extras --group lint`, so every CI run pulls msgspec/otel/niquests even though most tests don't need them. Declare a `test` extra (or move test-only deps into a dedicated dependency-group) and switch CI to the narrower install. Mild YAGNI today; revisit when extras grow heavier. (`pyproject.toml``[project.optional-dependencies]`, `Justfile:install`)
42
+
-**No `[test]` extra; CI installs all extras** — `just install` runs `uv sync --all-extras --group lint`, so every CI run pulls msgspec/otel/niquests even though most tests don't need them. Declare a `test` extra (or move test-only deps into a dedicated dependency-group) and switch CI to the narrower install. Mild YAGNI today; revisit when extras grow heavier. (`pyproject.toml``[project.optional-dependencies]`, `Justfile:install`)
0 commit comments