v0.2: thin httpx2 wrapper rewrite#20
Merged
Merged
Conversation
Twenty-three TDD tasks covering tear-down, errors, middleware, AsyncClient construction/send/per-method/response_model/middleware-wiring/lifecycle/ typing, docs (CLAUDE.md, engineering.md, deferred-work sweep), version bump, release notes, and final integration sweep. Single structural PR per spec. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove Request/Response/Config value types, Transport protocol, Httpx2Transport, RecordedTransport, auth coercion, and the no-leakage CI invariant. Decoders survive. New AsyncClient/errors/middleware land in subsequent commits.
…coverage gaps Wrap IPv6 hostnames in brackets after urlsplit strips them, preventing malformed URLs like https://::1:8080/x. Add four tests covering: port preservation, username-only userinfo, at-sign in query string only, and IPv6 host with credentials. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace three `# noqa: PLR2004` suppressions with named constants. Matches the constant-extraction pattern already used in test_errors.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In client.py: drop _CLIENT_ERROR_LOW/_SERVER_ERROR_LOW/_SERVER_ERROR_HIGH in favor of HTTPStatus.BAD_REQUEST/INTERNAL_SERVER_ERROR direct comparison. 600 is the only literal that stays (no stdlib equivalent for the synthetic 5xx upper bound); single noqa with justification, same pattern as the 0.1 transport. In tests/test_middleware.py: replace _STATUS_OK/_STATUS_UPGRADED/ _STATUS_SERVICE_UNAVAILABLE with HTTPStatus.OK / HTTPStatus.IM_USED / HTTPStatus.SERVICE_UNAVAILABLE. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add AsyncClient.send() (with response_model overloads) and build_request() delegating to the wrapped httpx2.AsyncClient. Tests cover 2xx passthrough, typed 4xx/5xx subclass raises, fallback to ClientStatusError/ServerStatusError, 3xx passthrough, timeout→TimeoutError, connect→TransportError, and closed-client→TransportError. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…options/request) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lient Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add targeted tests for uncovered branches in client.py (cookies/limits/auth kwargs, InvalidURL exception mapping, RuntimeError re-raise, and all _request_with_body optional-kwarg branches) and in middleware/__init__.py (__repr__ methods on before_request/after_response/on_error wrappers). Apply # pragma: no cover to test-helper methods that are structural placeholders never invoked (protocol-check __call__, default-arg guards, and the unreachable swallow_all body in the CancelledError test). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The engineering doc is a planning/architecture reference (alongside specs/, plans/, deferred-work.md), not user-facing documentation in docs/. Move it under planning/ and update the live references in CLAUDE.md and the v0.2 spec. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reframes
httpwareas a thin opinionated wrapper aroundhttpx2. Per the spec atplanning/specs/2026-06-03-thin-httpx2-wrapper-design.md.What stays:
AsyncClientwithget/post/put/patch/delete/head/options/request(response_model overloads → typed decoding).__init__(retyped onhttpx2.Request/httpx2.Response),@before_request/@after_response/@on_errordecorators.NotFoundError,RateLimitedError, ...) auto-raised on 4xx/5xx.What's gone:
Request/Response/StreamResponse/Limits/Timeout/ClientConfigvalue types — usehttpx2.*directly.Transportprotocol +Httpx2Transport+RecordedTransport— tests injecthttpx2.MockTransportvia the newhttpx2_client=kwarg.httpx2.Auth(e.g.,httpx2.BasicAuth) directly.with_optionsview pattern.httpx2leakage" CI invariant (and its test) —httpx2.Request/httpx2.Responseare now part of the public surface.Numbers: 18 commits, +1537/−3986 net (~2.4k LOC deleted). Five protocol seams collapse to three. 27-story roadmap shrinks to ~16. 119 tests pass at 100% coverage.
Version bumped to
0.2.0; release notes drafted atplanning/specs/2026-06-03-release-notes-0.2.0.md.Test plan
just test— 119 passed, 100% coverage.just lint-ci— eof-fixer / ruff format / ruff check / ty all clean.import httpwarein a clean subprocess does not pullmsgspec(optional-extras isolation).Request,Response,Transport, etc.).🤖 Generated with Claude Code