Skip to content

Commit

Permalink
Merge branch 'main' into binary_subscr
Browse files Browse the repository at this point in the history
  • Loading branch information
iritkatriel authored Jan 28, 2025
2 parents 6bb9978 + 7dd0a7e commit fa072fd
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 8 deletions.
13 changes: 7 additions & 6 deletions Lib/_pyio.py
Original file line number Diff line number Diff line change
Expand Up @@ -1692,13 +1692,14 @@ def readall(self):

return bytes(result)

def readinto(self, b):
def readinto(self, buffer):
"""Same as RawIOBase.readinto()."""
m = memoryview(b).cast('B')
data = self.read(len(m))
n = len(data)
m[:n] = data
return n
self._checkClosed()
self._checkReadable()
try:
return os.readinto(self._fd, buffer)
except BlockingIOError:
return None

def write(self, b):
"""Write bytes b to file, return number written.
Expand Down
2 changes: 1 addition & 1 deletion Lib/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class HTTPMethod:
Methods from the following RFCs are all observed:
* RFF 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616
* RFC 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616
* RFC 5789: PATCH Method for HTTP
"""
def __new__(cls, value, description):
Expand Down
4 changes: 3 additions & 1 deletion Lib/http/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ def read(self, amt=None):
if self.chunked:
return self._read_chunked(amt)

if amt is not None:
if amt is not None and amt >= 0:
if self.length is not None and amt > self.length:
# clip the read to the "end of response"
amt = self.length
Expand Down Expand Up @@ -590,6 +590,8 @@ def _get_chunk_left(self):

def _read_chunked(self, amt=None):
assert self.chunked != _UNKNOWN
if amt is not None and amt < 0:
amt = None
value = []
try:
while (chunk_left := self._get_chunk_left()) is not None:
Expand Down
19 changes: 19 additions & 0 deletions Lib/test/test_httplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,25 @@ def test_chunked(self):
self.assertEqual(resp.read(), expected)
resp.close()

# Explicit full read
for n in (-123, -1, None):
with self.subTest('full read', n=n):
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
resp = client.HTTPResponse(sock, method="GET")
resp.begin()
self.assertTrue(resp.chunked)
self.assertEqual(resp.read(n), expected)
resp.close()

# Read first chunk
with self.subTest('read1(-1)'):
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
resp = client.HTTPResponse(sock, method="GET")
resp.begin()
self.assertTrue(resp.chunked)
self.assertEqual(resp.read1(-1), b"hello worl")
resp.close()

# Various read sizes
for n in range(1, 12):
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix incorrect handling of negative read sizes in :meth:`HTTPResponse.read
<http.client.HTTPResponse.read>`. Patch by Yury Manushkin.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Optimize ``_pyio.FileIO.readinto`` by avoiding unnecessary objects and copies using :func:`os.readinto`.

0 comments on commit fa072fd

Please sign in to comment.