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
{{ message }}
Repository navigation
Remove _merge_url_query once httpx2 merges params into the URL query #146
httpx2 replaces a URL's query string whenever params are sent, including client-level params (pydantic/httpx2#905). httpware works around this in src/httpware/client.py: #145 (0.17.1) added the workaround, and #156 replaced it with _build_request, which strips the URL's query, lets httpx2 build the request, then puts the original query bytes back in front of the params. stream() goes through _stream / _stream_async for the same reason. Semantics match requests and pydantic/httpx2#966: params are appended after the URL's query, duplicate keys are kept, and the URL's query bytes are not re-encoded.
Blocked on
An httpx2 release that merges params into the existing URL query. Candidate fix: pydantic/httpx2#966 (open, unreviewed as of 2026-10-03). An earlier attempt, pydantic/httpx2#1026, was closed unmerged.
When unblocked
Check upstream semantics still match ours: params appended after the URL query, duplicate keys kept, client params before per-request params, params={} keeps the URL query, URL query bytes unchanged.
Raise the httpx2 floor in pyproject.toml to the release containing the fix.
Replace every _build_request(client, method, url, kwargs) call (build_request, _prepare_request and the capped stream helpers, in both worlds) with client.build_request(method, url, **kwargs), and delete _build_request. The uncapped stream() path can go back to self._httpx2_client.stream, dropping _stream / _stream_async.
Keep tests/test_url_query_merge.py: it passes 50/50 against #966 (2631c38) with the workaround stubbed out, so it should pass unchanged. If a case fails, upstream semantics differ from #966 and that is a behaviour change to call out in the release.
Ran tests/test_url_query_merge.py against pydantic/httpx2#966 (2631c38) with _merge_url_query stubbed to a pass-through. #966 appends params to the existing query instead of merging, so 3 of 7 cases fail:
The other four cases pass. With the workaround left in place, the whole suite passes on #966.
If #966 lands as written, removing _merge_url_query would mean per-request params no longer override a key already in the URL, and that key would be sent twice.
Since the analysis above: requests also appends (?a=1 + params={"a": "2"} gives ?a=1&a=2), so #966's behaviour matches requests and httpware's override was the outlier. #156 switches httpware to append and keeps the URL's query bytes unchanged. With it, tests/test_url_query_merge.py passes 50/50 against #966 with the workaround stubbed out. Once #156 merges, step 1 here holds as-is, and step 3 means deleting _build_request and the _stream/_stream_async helpers rather than _merge_url_query.
Activity
lesnik512 commentedon Oct 3, 2026
Ran
tests/test_url_query_merge.pyagainst pydantic/httpx2#966 (2631c38) with_merge_url_querystubbed to a pass-through. #966 appends params to the existing query instead of merging, so 3 of 7 cases fail:params-override-same-key(?a=1&b=1+b=2)a=1&b=2a=1&b=1&b=2url-query-overrides-client(?a=1&c=1, clientc=3,b=2)c=1&a=1&b=2a=1&c=1&c=3&b=2client-params-keep-url-queryc=3&a=1a=1&c=3The other four cases pass. With the workaround left in place, the whole suite passes on #966.
If #966 lands as written, removing
_merge_url_querywould mean per-request params no longer override a key already in the URL, and that key would be sent twice.lesnik512 commentedon Oct 4, 2026
Since the analysis above:
requestsalso appends (?a=1+params={"a": "2"}gives?a=1&a=2), so #966's behaviour matchesrequestsand httpware's override was the outlier. #156 switches httpware to append and keeps the URL's query bytes unchanged. With it,tests/test_url_query_merge.pypasses 50/50 against #966 with the workaround stubbed out. Once #156 merges, step 1 here holds as-is, and step 3 means deleting_build_requestand the_stream/_stream_asynchelpers rather than_merge_url_query.