Skip to content

Commit b7dc0c3

Browse files
authored
Fix for stream uploads that subclass SyncByteStream/AsyncByteStream (#2016)
1 parent 99ba25c commit b7dc0c3

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

httpx/_content.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ def __iter__(self) -> Iterator[bytes]:
5050
raise StreamConsumed()
5151

5252
self._is_stream_consumed = True
53-
if hasattr(self._stream, "read"):
53+
if hasattr(self._stream, "read") and not isinstance(
54+
self._stream, SyncByteStream
55+
):
5456
# File-like interfaces should use 'read' directly.
5557
chunk = self._stream.read(self.CHUNK_SIZE) # type: ignore
5658
while chunk:
@@ -75,7 +77,9 @@ async def __aiter__(self) -> AsyncIterator[bytes]:
7577
raise StreamConsumed()
7678

7779
self._is_stream_consumed = True
78-
if hasattr(self._stream, "aread"):
80+
if hasattr(self._stream, "aread") and not isinstance(
81+
self._stream, AsyncByteStream
82+
):
7983
# File-like interfaces should use 'aread' directly.
8084
chunk = await self._stream.aread(self.CHUNK_SIZE) # type: ignore
8185
while chunk:

tests/test_api.py

+12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ def data():
2828
assert response.reason_phrase == "OK"
2929

3030

31+
def test_post_byte_stream(server):
32+
class Data(httpx.SyncByteStream):
33+
def __iter__(self):
34+
yield b"Hello"
35+
yield b", "
36+
yield b"world!"
37+
38+
response = httpx.post(server.url, content=Data())
39+
assert response.status_code == 200
40+
assert response.reason_phrase == "OK"
41+
42+
3143
def test_options(server):
3244
response = httpx.options(server.url)
3345
assert response.status_code == 200

0 commit comments

Comments
 (0)