From c30a7e379255627125afe562f31dfc2213069027 Mon Sep 17 00:00:00 2001 From: -LAN- Date: Fri, 8 Nov 2024 14:49:53 +0800 Subject: [PATCH 1/5] feat(content): allow multipart requests without files. --- httpx/_content.py | 2 +- httpx/_main.py | 2 +- tests/test_content.py | 14 ++++++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/httpx/_content.py b/httpx/_content.py index 6f479a0885..2579fd39e3 100644 --- a/httpx/_content.py +++ b/httpx/_content.py @@ -208,7 +208,7 @@ def encode_request( if content is not None: return encode_content(content) - elif files: + elif files is not None: return encode_multipart_data(data or {}, files, boundary) elif data: return encode_urlencoded_data(data) diff --git a/httpx/_main.py b/httpx/_main.py index 3df37cf0ae..0fe9b4176b 100644 --- a/httpx/_main.py +++ b/httpx/_main.py @@ -487,7 +487,7 @@ def main( params=list(params), content=content, data=dict(data), - files=files, # type: ignore + files=files or None, # type: ignore json=json, headers=headers, cookies=dict(cookies), diff --git a/tests/test_content.py b/tests/test_content.py index 053f52eac4..499e229924 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -4,7 +4,8 @@ import pytest import httpx -from httpx._content import encode_json +from httpx._content import encode_json, encode_request +from httpx._types import SyncByteStream method = "POST" url = "https://www.example.com" @@ -345,7 +346,7 @@ async def test_multipart_data_and_files_content(): @pytest.mark.anyio async def test_empty_request(): - request = httpx.Request(method, url, data={}, files={}) + request = httpx.Request(method, url, data={}) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) @@ -521,3 +522,12 @@ def test_allow_nan_false(): ValueError, match="Out of range float values are not JSON compliant" ): encode_json(data_with_inf) + + +def test_encode_request_with_data_and_empty_files(): + headers, stream = encode_request(data={"key": "value"}, files={}) + assert headers["Content-Type"].startswith("multipart/form-data; boundary=") + assert isinstance(stream, SyncByteStream) + stream_content = b"".join(stream) + assert b'Content-Disposition: form-data; name="key"' in stream_content + assert b"value" in stream_content From f95919830bcc9da839b32c6475be3bc8ab0ed2e4 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Nov 2024 11:22:27 +0000 Subject: [PATCH 2/5] Update tests/test_content.py --- tests/test_content.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_content.py b/tests/test_content.py index 47b50ff2c0..55c2b088b5 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -520,7 +520,12 @@ def test_allow_nan_false(): def test_encode_request_with_data_and_empty_files(): - request = httpx.Request(data={"key": "value"}, files={}) + request = httpx.Request( + url="https://www.example.com", + method="POST", + data={"key": "value"}, + files={} + ) assert request.headers["Content-Type"].startswith("multipart/form-data; boundary=") request.read() assert b'Content-Disposition: form-data; name="key"' in request.content From 0d632c825df0d98254404e15454b4f72ac540de3 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Nov 2024 11:23:58 +0000 Subject: [PATCH 3/5] Update tests/test_content.py --- tests/test_content.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/test_content.py b/tests/test_content.py index 55c2b088b5..2769fdf3f8 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -520,12 +520,7 @@ def test_allow_nan_false(): def test_encode_request_with_data_and_empty_files(): - request = httpx.Request( - url="https://www.example.com", - method="POST", - data={"key": "value"}, - files={} - ) + request = httpx.Request(url="https://www.example.com", method="POST", data={"key": "value"}, files={}) assert request.headers["Content-Type"].startswith("multipart/form-data; boundary=") request.read() assert b'Content-Disposition: form-data; name="key"' in request.content From 1b05319a06864f055684ab278a784117177f0ee6 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Nov 2024 11:25:19 +0000 Subject: [PATCH 4/5] Update tests/test_content.py --- tests/test_content.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_content.py b/tests/test_content.py index 2769fdf3f8..67e48c7683 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -520,7 +520,9 @@ def test_allow_nan_false(): def test_encode_request_with_data_and_empty_files(): - request = httpx.Request(url="https://www.example.com", method="POST", data={"key": "value"}, files={}) + request = httpx.Request( + url="https://www.example.com", method="POST", data={"key": "value"}, files={} + ) assert request.headers["Content-Type"].startswith("multipart/form-data; boundary=") request.read() assert b'Content-Disposition: form-data; name="key"' in request.content From 2dd32df51453931c385cb9ac806cefa101bf03a7 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Nov 2024 11:28:26 +0000 Subject: [PATCH 5/5] Update tests/test_content.py --- tests/test_content.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_content.py b/tests/test_content.py index 67e48c7683..6c968a3feb 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -5,7 +5,6 @@ import httpx - method = "POST" url = "https://www.example.com"