Problem
fetch() promises to add Content-Type: application/json for a mapping body only when the caller hasn't supplied a content type. In src/pythonnative/net.py, _build_request() uses the case-sensitive header_dict.setdefault("Content-Type", ...). A lowercase header creates a second entry, and urllib.request.Request normalizes both names, overwriting the caller's value.
Confirmed on the linked revision: a POST with headers={"content-type": "application/merge-patch+json"} and body={"name": "Ada"} produces [("Content-type", "application/json")] in request.header_items(). This can change how an API interprets the payload.
Requested change
Check for an existing content-type header case-insensitively before adding the JSON default. Keep the caller's supplied value and the existing JSON body encoding.
Acceptance criteria
- Parameterized tests cover Content-Type, content-type, CONTENT-TYPE, and mixed casing, preserving application/merge-patch+json in every case.
- The resulting request contains exactly one content-type header.
- A mapping body without a supplied content type still gets application/json.
- The caller's headers mapping is unchanged, and the request body still decodes to the original JSON object.
Starting points and verification
Extend tests/test_net.py. Construct requests with _build_request() for these tests; no server, device, or network is required. This issue concerns request header defaults; URL query assembly is a separate task.
uv run pytest tests/test_net.py -q
./scripts/check.sh
Suggested commit message
Following CONTRIBUTING.md:
fix(net): preserve custom content type regardless of header casing
Before starting
Please follow the issue-claiming process: check for an assignee or linked pull request, comment to claim the issue, and wait for a maintainer to assign it before opening a pull request. Contributor setup is in CONTRIBUTING.md.
Problem
fetch() promises to add Content-Type: application/json for a mapping body only when the caller hasn't supplied a content type. In src/pythonnative/net.py, _build_request() uses the case-sensitive header_dict.setdefault("Content-Type", ...). A lowercase header creates a second entry, and urllib.request.Request normalizes both names, overwriting the caller's value.
Confirmed on the linked revision: a POST with headers={"content-type": "application/merge-patch+json"} and body={"name": "Ada"} produces [("Content-type", "application/json")] in request.header_items(). This can change how an API interprets the payload.
Requested change
Check for an existing content-type header case-insensitively before adding the JSON default. Keep the caller's supplied value and the existing JSON body encoding.
Acceptance criteria
Starting points and verification
Extend tests/test_net.py. Construct requests with _build_request() for these tests; no server, device, or network is required. This issue concerns request header defaults; URL query assembly is a separate task.
Suggested commit message
Following CONTRIBUTING.md:
Before starting
Please follow the issue-claiming process: check for an assignee or linked pull request, comment to claim the issue, and wait for a maintainer to assign it before opening a pull request. Contributor setup is in CONTRIBUTING.md.