Skip to content

Commit fa072fd

Browse files
authored
Merge branch 'main' into binary_subscr
2 parents 6bb9978 + 7dd0a7e commit fa072fd

File tree

6 files changed

+33
-8
lines changed

6 files changed

+33
-8
lines changed

Lib/_pyio.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,13 +1692,14 @@ def readall(self):
16921692

16931693
return bytes(result)
16941694

1695-
def readinto(self, b):
1695+
def readinto(self, buffer):
16961696
"""Same as RawIOBase.readinto()."""
1697-
m = memoryview(b).cast('B')
1698-
data = self.read(len(m))
1699-
n = len(data)
1700-
m[:n] = data
1701-
return n
1697+
self._checkClosed()
1698+
self._checkReadable()
1699+
try:
1700+
return os.readinto(self._fd, buffer)
1701+
except BlockingIOError:
1702+
return None
17021703

17031704
def write(self, b):
17041705
"""Write bytes b to file, return number written.

Lib/http/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class HTTPMethod:
190190
191191
Methods from the following RFCs are all observed:
192192
193-
* RFF 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616
193+
* RFC 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616
194194
* RFC 5789: PATCH Method for HTTP
195195
"""
196196
def __new__(cls, value, description):

Lib/http/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ def read(self, amt=None):
472472
if self.chunked:
473473
return self._read_chunked(amt)
474474

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

591591
def _read_chunked(self, amt=None):
592592
assert self.chunked != _UNKNOWN
593+
if amt is not None and amt < 0:
594+
amt = None
593595
value = []
594596
try:
595597
while (chunk_left := self._get_chunk_left()) is not None:

Lib/test/test_httplib.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,25 @@ def test_chunked(self):
10921092
self.assertEqual(resp.read(), expected)
10931093
resp.close()
10941094

1095+
# Explicit full read
1096+
for n in (-123, -1, None):
1097+
with self.subTest('full read', n=n):
1098+
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
1099+
resp = client.HTTPResponse(sock, method="GET")
1100+
resp.begin()
1101+
self.assertTrue(resp.chunked)
1102+
self.assertEqual(resp.read(n), expected)
1103+
resp.close()
1104+
1105+
# Read first chunk
1106+
with self.subTest('read1(-1)'):
1107+
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
1108+
resp = client.HTTPResponse(sock, method="GET")
1109+
resp.begin()
1110+
self.assertTrue(resp.chunked)
1111+
self.assertEqual(resp.read1(-1), b"hello worl")
1112+
resp.close()
1113+
10951114
# Various read sizes
10961115
for n in range(1, 12):
10971116
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix incorrect handling of negative read sizes in :meth:`HTTPResponse.read
2+
<http.client.HTTPResponse.read>`. Patch by Yury Manushkin.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Optimize ``_pyio.FileIO.readinto`` by avoiding unnecessary objects and copies using :func:`os.readinto`.

0 commit comments

Comments
 (0)