From 3e93accd18b5dff5e7918132ed61b128fe5a3c24 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Fri, 12 Dec 2025 15:10:24 -0800 Subject: [PATCH 1/3] Fix urlretrieve reporthook to report actual bytes read --- Lib/test/test_urllib.py | 2 +- Lib/urllib/request.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index ae524c5ffba6b1..a468b115752819 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -727,7 +727,7 @@ def hooktester(block_count, block_read_size, file_size, _report=report): self.assertEqual(report[0][2], 8193) self.assertEqual(report[0][1], 8192) self.assertEqual(report[1][1], 8192) - self.assertEqual(report[2][1], 8192) + self.assertEqual(report[2][1], 1) # last block only reads 1 byte class urlretrieve_HttpTests(unittest.TestCase, FakeHTTPMixin): diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 566b8087aec277..6052e4cb202e96 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -242,7 +242,7 @@ def urlretrieve(url, filename=None, reporthook=None, data=None): tfp.write(block) blocknum += 1 if reporthook: - reporthook(blocknum, bs, size) + reporthook(blocknum, len(block), size) if size >= 0 and read < size: raise ContentTooShortError( From 295fcbc97023bab1c818c1a121fbd8af623eaecd Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 23:17:15 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-12-12-23-17-10.gh-issue-43374.M6jGC5.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-12-12-23-17-10.gh-issue-43374.M6jGC5.rst diff --git a/Misc/NEWS.d/next/Library/2025-12-12-23-17-10.gh-issue-43374.M6jGC5.rst b/Misc/NEWS.d/next/Library/2025-12-12-23-17-10.gh-issue-43374.M6jGC5.rst new file mode 100644 index 00000000000000..0fe3c35ab3fc1d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-12-23-17-10.gh-issue-43374.M6jGC5.rst @@ -0,0 +1 @@ +Fix :func:`urllib.request.urlretrieve` to pass the actual number of bytes read to the *reporthook* callback, instead of always passing the block size. From 5c66bd1a27f5c5e6ca70f1b965ee924faf24dddd Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Fri, 12 Dec 2025 15:32:45 -0800 Subject: [PATCH 3/3] Fix test --- Lib/test/test_urllibnet.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index 1a42c35dc49b9e..da094752b84c62 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -219,12 +219,14 @@ def recording_reporthook(blocks, block_size, total_size): self.assertEqual(records[0][2], expected_size) self.assertEqual(records[-1][2], expected_size) - block_sizes = {block_size for _, block_size, _ in records} - self.assertEqual({records[0][1]}, block_sizes, - msg="block sizes in %s must be equal" % records_repr) - self.assertGreaterEqual(records[-1][0]*records[0][1], expected_size, - msg="number of blocks * block size must be" - " >= total size in %s" % records_repr) + self.assertEqual(records[0][1], 8192, + msg="first block size should be 8192 in %s" % records_repr) + for block_num, block_size, total_size in records: + self.assertLessEqual(block_size, 8192, + msg="block size should be <= 8192 in %s" % records_repr) + total_read = sum(block_size for _, block_size, _ in records[1:]) + self.assertEqual(total_read, expected_size, + msg="sum of bytes read must equal total size in %s" % records_repr) if __name__ == "__main__":