From 14f279b23e7756e193f5a5eb2c32a8dde10e4be0 Mon Sep 17 00:00:00 2001 From: BERRADA-Omar Date: Sat, 26 Oct 2024 17:44:26 +0200 Subject: [PATCH 1/6] Ignore .vscode/ directory and fix encoding issue in test_whatwg.py --- .gitignore | 1 + tests/models/test_whatwg.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 49e14ccc8d..4d8962d902 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ venv*/ .python-version build/ dist/ +.vscode/ \ No newline at end of file diff --git a/tests/models/test_whatwg.py b/tests/models/test_whatwg.py index 6e00a921ae..14af682586 100644 --- a/tests/models/test_whatwg.py +++ b/tests/models/test_whatwg.py @@ -10,7 +10,7 @@ # 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 From fa44a610c2992bb3b6c229a0471a276574c60980 Mon Sep 17 00:00:00 2001 From: BERRADA-Omar Date: Sat, 26 Oct 2024 18:09:45 +0200 Subject: [PATCH 2/6] Ensure JSON representation is compact. #3363 --- httpx/_content.py | 2 +- tests/test_content.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/httpx/_content.py b/httpx/_content.py index 786699f38f..ca460d9c74 100644 --- a/httpx/_content.py +++ b/httpx/_content.py @@ -174,7 +174,7 @@ def encode_html(html: str) -> tuple[dict[str, str], ByteStream]: 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} diff --git a/tests/test_content.py b/tests/test_content.py index 21c92dd799..0b302b64a0 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -4,6 +4,7 @@ import pytest import httpx +from httpx._content import encode_json method = "POST" url = "https://www.example.com" @@ -484,3 +485,29 @@ async def hello_world() -> typing.AsyncIterator[bytes]: 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) \ No newline at end of file From 682344833128094a91575883385347997f4e9e17 Mon Sep 17 00:00:00 2001 From: BERRADA-Omar Date: Sat, 26 Oct 2024 18:25:10 +0200 Subject: [PATCH 3/6] format _content.py & test_content.py --- httpx/_content.py | 4 +++- tests/test_content.py | 26 ++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/httpx/_content.py b/httpx/_content.py index ca460d9c74..95a47258d6 100644 --- a/httpx/_content.py +++ b/httpx/_content.py @@ -174,7 +174,9 @@ def encode_html(html: str) -> tuple[dict[str, str], ByteStream]: def encode_json(json: Any) -> tuple[dict[str, str], ByteStream]: - body = json_dumps(json, ensure_ascii=False, separators=(",", ":"), allow_nan=False).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} diff --git a/tests/test_content.py b/tests/test_content.py index 0b302b64a0..81b67a6a9a 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -491,23 +491,33 @@ 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 ( + "ç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 ( + 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"): + + 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) \ No newline at end of file + with pytest.raises( + ValueError, match="Out of range float values are not JSON compliant" + ): + encode_json(data_with_inf) From ea8d7bc6886e95f23f0de275034cc51ffa7190b1 Mon Sep 17 00:00:00 2001 From: BERRADA-Omar Date: Sat, 26 Oct 2024 18:41:05 +0200 Subject: [PATCH 4/6] fix failing tests --- tests/client/test_auth.py | 4 ++-- tests/models/test_requests.py | 8 ++++---- tests/models/test_responses.py | 4 ++-- tests/test_content.py | 6 +++--- tests/test_main.py | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/client/test_auth.py b/tests/client/test_auth.py index 5776fc33ba..b3aeaf4e4b 100644 --- a/tests/client/test_auth.py +++ b/tests/client/test_auth.py @@ -743,7 +743,7 @@ async def test_async_auth_reads_response_body() -> None: 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: @@ -759,7 +759,7 @@ 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 diff --git a/tests/models/test_requests.py b/tests/models/test_requests.py index ad6d6705f2..d2a458d57e 100644 --- a/tests/models/test_requests.py +++ b/tests/models/test_requests.py @@ -62,7 +62,7 @@ def test_json_encoded_data(): request.read() assert request.headers["Content-Type"] == "application/json" - assert request.content == b'{"test": 123}' + assert request.content == b'{"test":123}' def test_headers(): @@ -71,7 +71,7 @@ def test_headers(): assert request.headers == { "Host": "example.org", "Content-Type": "application/json", - "Content-Length": "13", + "Content-Length": "12", } @@ -183,12 +183,12 @@ def test_request_picklable(): 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", } diff --git a/tests/models/test_responses.py b/tests/models/test_responses.py index d639625825..06c28e1e30 100644 --- a/tests/models/test_responses.py +++ b/tests/models/test_responses.py @@ -81,9 +81,9 @@ def test_response_json(): 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", } diff --git a/tests/test_content.py b/tests/test_content.py index 81b67a6a9a..053f52eac4 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -174,11 +174,11 @@ async def test_json_content(): 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 diff --git a/tests/test_main.py b/tests/test_main.py index feb796e155..b1a77d485b 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -114,7 +114,7 @@ def test_post(server): "content-type: text/plain", "Transfer-Encoding: chunked", "", - '{"hello": "world"}', + '{"hello":"world"}', ] From 0f83f96737a7343445817600b038bc7c134ee436 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 28 Oct 2024 09:17:41 +0000 Subject: [PATCH 5/6] Update .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4d8962d902..4b34d9a594 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ site/ venv*/ .python-version build/ -dist/ -.vscode/ \ No newline at end of file +dist/ \ No newline at end of file From d30d725178a2f20e8946ea00916deb5652577106 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 28 Oct 2024 09:17:56 +0000 Subject: [PATCH 6/6] Update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4b34d9a594..49e14ccc8d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ site/ venv*/ .python-version build/ -dist/ \ No newline at end of file +dist/