0.8.5 — small fixes mop-up
httpware 0.8.5 — small fixes mop-up
Patch release. Four small unrelated fixes. No API change, no user-visible behavior change on the happy path. Closes 4 of the remaining audit findings — two Low (chain.py + pydantic.py), two Nit (LoggingMiddleware docs + public-API test).
What changed
-
typing.get_type_hints(compose_async)andtyping.get_type_hints(compose)now resolve cleanly. TheAsyncMiddleware/Middlewareimports moved out of theif typing.TYPE_CHECKING:guard inhttpware/middleware/chain.py; runtime introspection of the chain-composition signatures works. No behavior change for users not callingget_type_hints. -
PydanticDecoderno longer has a NameError window on test-reload.httpware/decoders/pydantic.pynow importspydantic.TypeAdapterunconditionally at module top. The optional-extras gate is enforced upstream byclient.py:_default_pydantic_decoder(), so loading this module without pydantic was already not a real-world path. The previous conditional import leftTypeAdapterundefined when the install flag was patched off, raisingNameErrorinstead of the documentedImportErrorif anyone reloaded the module under the flag patch. -
LoggingMiddlewareexample indocs/middleware.mduseslogging, notprint(). CLAUDE.md lists "Noprint()" as a non-negotiable invariant; copying the example into a user's project would have failed their own ruff check. The new snippet mirrors theRequestIdMiddlewarestyle further down the same file. -
Public-API test catches bogus
__all__entries.test_expected_exportspreviously checked onlyexpected - set(__all__); now it asserts set equality so a symbol added to__all__without a peer update to the expected set is also caught.
Upgrade
uv add httpware==0.8.5
# or
pip install -U 'httpware==0.8.5'No import changes. No API changes. The only behavior change is that from httpware.decoders.pydantic import PydanticDecoder now fails with a real ImportError at import time when pydantic isn't installed (instead of succeeding-then-failing-at-construct). The audit finding documented that the previous behavior was unreachable in practice — the upstream fail-fast at _default_pydantic_decoder() is the real safety net.