]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Fix for stream uploads that subclass SyncByteStream/AsyncByteStream (#2016)
authorTom Christie <tom@tomchristie.com>
Thu, 6 Jan 2022 14:06:35 +0000 (14:06 +0000)
committerGitHub <noreply@github.com>
Thu, 6 Jan 2022 14:06:35 +0000 (14:06 +0000)
httpx/_content.py
tests/test_api.py

index f210c4a80c9f325cf834a8ef04f93252c8d81c98..4871a8de2df16cd3bf4655870d6c189e3fcc7ae8 100644 (file)
@@ -50,7 +50,9 @@ class IteratorByteStream(SyncByteStream):
             raise StreamConsumed()
 
         self._is_stream_consumed = True
-        if hasattr(self._stream, "read"):
+        if hasattr(self._stream, "read") and not isinstance(
+            self._stream, SyncByteStream
+        ):
             # File-like interfaces should use 'read' directly.
             chunk = self._stream.read(self.CHUNK_SIZE)  # type: ignore
             while chunk:
@@ -75,7 +77,9 @@ class AsyncIteratorByteStream(AsyncByteStream):
             raise StreamConsumed()
 
         self._is_stream_consumed = True
-        if hasattr(self._stream, "aread"):
+        if hasattr(self._stream, "aread") and not isinstance(
+            self._stream, AsyncByteStream
+        ):
             # File-like interfaces should use 'aread' directly.
             chunk = await self._stream.aread(self.CHUNK_SIZE)  # type: ignore
             while chunk:
index b6c2421af4d078ea9715c93822f7b1fc123ff4e7..22ab79696d75929cb87c03a5876965c1d1393747 100644 (file)
@@ -28,6 +28,18 @@ def test_post_byte_iterator(server):
     assert response.reason_phrase == "OK"
 
 
+def test_post_byte_stream(server):
+    class Data(httpx.SyncByteStream):
+        def __iter__(self):
+            yield b"Hello"
+            yield b", "
+            yield b"world!"
+
+    response = httpx.post(server.url, content=Data())
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"
+
+
 def test_options(server):
     response = httpx.options(server.url)
     assert response.status_code == 200