Fix confusing error message for invalid data parameter
When AsyncClient receives invalid data like data=[{"a": "b"}] (list of dicts),
it was raising "Attempted to send a sync request with an AsyncClient instance"
which is misleading. The actual issue is invalid data format.
This fix adds early validation in encode_request() to check if data is a
list/tuple containing non-bytes objects, and raises a clear TypeError with
helpful guidance (use json= or data={...} instead).
Fixes #3471
This commit is contained in:
parent
b5addb64f0
commit
a5e4db62be
@ -202,6 +202,21 @@ def encode_request(
|
||||
# However for compat with requests, we *do* still support
|
||||
# `data=<bytes...>` usages. We deal with that case here, treating it
|
||||
# as if `content=<...>` had been supplied instead.
|
||||
|
||||
# Validate that data is bytes-like or an iterable of bytes, not other types
|
||||
if isinstance(data, (list, tuple)):
|
||||
# Check if it's a list/tuple of bytes
|
||||
try:
|
||||
for item in data:
|
||||
if not isinstance(item, (bytes, bytearray, memoryview)):
|
||||
raise TypeError(
|
||||
f"Expected bytes-like object in 'data' sequence, got {type(item).__name__}. "
|
||||
f"Use 'json=' for JSON data or 'data={{...}}' for form data."
|
||||
)
|
||||
except TypeError:
|
||||
# Re-raise our custom error, not the iteration error
|
||||
raise
|
||||
|
||||
message = "Use 'content=<...>' to upload raw bytes/text content."
|
||||
warnings.warn(message, DeprecationWarning, stacklevel=2)
|
||||
return encode_content(data)
|
||||
|
||||
@ -364,6 +364,27 @@ def test_invalid_argument():
|
||||
httpx.Request(method, url, content={"a": "b"}) # type: ignore
|
||||
|
||||
|
||||
def test_invalid_data_list_of_dicts():
|
||||
"""Test that passing a list of dicts to data= produces a clear error message.
|
||||
|
||||
This was previously raising a confusing 'Attempted to send a sync request
|
||||
with an AsyncClient instance' error with AsyncClient. Now it should give
|
||||
a clear error for both sync and async clients.
|
||||
"""
|
||||
with pytest.raises(TypeError, match="Expected bytes-like object.*got dict"):
|
||||
httpx.Request(method, url, data=[{"a": "b"}]) # type: ignore
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_invalid_data_list_of_dicts_async():
|
||||
"""Test that AsyncClient produces clear error for invalid data parameter.
|
||||
|
||||
Regression test for issue #3471.
|
||||
"""
|
||||
with pytest.raises(TypeError, match="Expected bytes-like object.*got dict"):
|
||||
httpx.Request(method, url, data=[{"a": "b"}]) # type: ignore
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_multipart_multiple_files_single_input_content():
|
||||
files = [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user