def encode_json(json: Any) -> tuple[dict[str, str], ByteStream]:
- body = json_dumps(json).encode("utf-8")
+ body = json_dumps(
+ json, ensure_ascii=False, separators=(",", ":"), allow_nan=False
+ ).encode("utf-8")
content_length = str(len(body))
content_type = "application/json"
headers = {"Content-Length": content_length, "Content-Type": content_type}
response = await client.get(url, auth=auth)
assert response.status_code == 200
- assert response.json() == {"auth": '{"auth": "xyz"}'}
+ assert response.json() == {"auth": '{"auth":"xyz"}'}
def test_sync_auth_reads_response_body() -> None:
response = client.get(url, auth=auth)
assert response.status_code == 200
- assert response.json() == {"auth": '{"auth": "xyz"}'}
+ assert response.json() == {"auth": '{"auth":"xyz"}'}
@pytest.mark.anyio
request.read()
assert request.headers["Content-Type"] == "application/json"
- assert request.content == b'{"test": 123}'
+ assert request.content == b'{"test":123}'
def test_headers():
assert request.headers == {
"Host": "example.org",
"Content-Type": "application/json",
- "Content-Length": "13",
+ "Content-Length": "12",
}
assert pickle_request.method == "POST"
assert pickle_request.url.path == "/"
assert pickle_request.headers["Content-Type"] == "application/json"
- assert pickle_request.content == b'{"test": 123}'
+ assert pickle_request.content == b'{"test":123}'
assert pickle_request.stream is not None
assert request.headers == {
"Host": "example.org",
"Content-Type": "application/json",
- "content-length": "13",
+ "content-length": "12",
}
assert response.status_code == 200
assert response.reason_phrase == "OK"
- assert response.json() == {"hello": "world"}
+ assert str(response.json()) == "{'hello': 'world'}"
assert response.headers == {
- "Content-Length": "18",
+ "Content-Length": "17",
"Content-Type": "application/json",
}
# URL test cases from...
# https://github.com/web-platform-tests/wpt/blob/master/url/resources/urltestdata.json
-with open("tests/models/whatwg.json", "r") as input:
+with open("tests/models/whatwg.json", "r", encoding="utf-8") as input:
test_cases = json.load(input)
test_cases = [
item
import pytest
import httpx
+from httpx._content import encode_json
method = "POST"
url = "https://www.example.com"
assert request.headers == {
"Host": "www.example.com",
- "Content-Length": "19",
+ "Content-Length": "18",
"Content-Type": "application/json",
}
- assert sync_content == b'{"Hello": "world!"}'
- assert async_content == b'{"Hello": "world!"}'
+ assert sync_content == b'{"Hello":"world!"}'
+ assert async_content == b'{"Hello":"world!"}'
@pytest.mark.anyio
def test_response_invalid_argument():
with pytest.raises(TypeError):
httpx.Response(200, content=123) # type: ignore
+
+
+def test_ensure_ascii_false_with_french_characters():
+ data = {"greeting": "Bonjour, ça va ?"}
+ headers, byte_stream = encode_json(data)
+ json_output = b"".join(byte_stream).decode("utf-8")
+
+ assert (
+ "ça va" in json_output
+ ), "ensure_ascii=False should preserve French accented characters"
+ assert headers["Content-Type"] == "application/json"
+
+
+def test_separators_for_compact_json():
+ data = {"clé": "valeur", "liste": [1, 2, 3]}
+ headers, byte_stream = encode_json(data)
+ json_output = b"".join(byte_stream).decode("utf-8")
+
+ assert (
+ json_output == '{"clé":"valeur","liste":[1,2,3]}'
+ ), "separators=(',', ':') should produce a compact representation"
+ assert headers["Content-Type"] == "application/json"
+
+
+def test_allow_nan_false():
+ data_with_nan = {"nombre": float("nan")}
+ data_with_inf = {"nombre": float("inf")}
+
+ with pytest.raises(
+ ValueError, match="Out of range float values are not JSON compliant"
+ ):
+ encode_json(data_with_nan)
+ with pytest.raises(
+ ValueError, match="Out of range float values are not JSON compliant"
+ ):
+ encode_json(data_with_inf)
"content-type: text/plain",
"Transfer-Encoding: chunked",
"",
- '{"hello": "world"}',
+ '{"hello":"world"}',
]