Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-s3transfer for openSUSE:Factory checked in at 2026-11-06 19:57:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-s3transfer (Old) and /work/SRC/openSUSE:Factory/.python-s3transfer.new.3759290 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-s3transfer" Fri Nov 6 19:57:55 2026 rev:47 rq:1395797 version:0.19.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-s3transfer/python-s3transfer.changes 2026-08-20 16:17:35.792122811 +0200 +++ /work/SRC/openSUSE:Factory/.python-s3transfer.new.3759290/python-s3transfer.changes 2026-11-06 20:04:31.498709658 +0100 @@ -1,0 +2,7 @@ +Fri Nov 6 08:53:21 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to version 0.19.3 + * bugfix:ReadFileChunk: Keep reads with a negative size within + the chunk bounds. + +------------------------------------------------------------------- Old: ---- s3transfer-0.19.2.tar.gz New: ---- s3transfer-0.19.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-s3transfer.spec ++++++ --- /var/tmp/diff_new_pack.wiueOL/_old 2026-11-06 20:04:32.556753967 +0100 +++ /var/tmp/diff_new_pack.wiueOL/_new 2026-11-06 20:04:32.564754302 +0100 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-s3transfer -Version: 0.19.2 +Version: 0.19.3 Release: 0 Summary: Python S3 transfer manager License: Apache-2.0 ++++++ s3transfer-0.19.2.tar.gz -> s3transfer-0.19.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3transfer-0.19.2/PKG-INFO new/s3transfer-0.19.3/PKG-INFO --- old/s3transfer-0.19.2/PKG-INFO 2026-07-22 20:06:59.713466400 +0200 +++ new/s3transfer-0.19.3/PKG-INFO 2026-10-19 20:12:13.592751000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: s3transfer -Version: 0.19.2 +Version: 0.19.3 Summary: An Amazon S3 Transfer Manager Home-page: https://github.com/boto/s3transfer Author: Amazon Web Services diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3transfer-0.19.2/s3transfer/__init__.py new/s3transfer-0.19.3/s3transfer/__init__.py --- old/s3transfer-0.19.2/s3transfer/__init__.py 2026-07-22 20:06:59.000000000 +0200 +++ new/s3transfer-0.19.3/s3transfer/__init__.py 2026-10-19 20:12:13.000000000 +0200 @@ -145,7 +145,7 @@ from s3transfer.exceptions import RetriesExceededError, S3UploadFailedError __author__ = 'Amazon Web Services' -__version__ = '0.19.2' +__version__ = '0.19.3' logger = logging.getLogger(__name__) @@ -275,10 +275,11 @@ return min(max_chunk_size, requested_size) def read(self, amount=None): - if amount is None: - amount_to_read = self._size - self._amount_read + amount_left = max(self._size - self._amount_read, 0) + if amount is None or amount < 0: + amount_to_read = amount_left else: - amount_to_read = min(self._size - self._amount_read, amount) + amount_to_read = min(amount_left, amount) data = self._fileobj.read(amount_to_read) self._amount_read += len(data) if self._callback is not None and self._callback_enabled: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3transfer-0.19.2/s3transfer/utils.py new/s3transfer-0.19.3/s3transfer/utils.py --- old/s3transfer-0.19.2/s3transfer/utils.py 2026-07-22 20:02:00.000000000 +0200 +++ new/s3transfer-0.19.3/s3transfer/utils.py 2026-10-19 20:12:13.000000000 +0200 @@ -519,7 +519,7 @@ def read(self, amount=None): amount_left = max(self._size - self._amount_read, 0) - if amount is None: + if amount is None or amount < 0: amount_to_read = amount_left else: amount_to_read = min(amount_left, amount) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3transfer-0.19.2/s3transfer.egg-info/PKG-INFO new/s3transfer-0.19.3/s3transfer.egg-info/PKG-INFO --- old/s3transfer-0.19.2/s3transfer.egg-info/PKG-INFO 2026-07-22 20:06:59.000000000 +0200 +++ new/s3transfer-0.19.3/s3transfer.egg-info/PKG-INFO 2026-10-19 20:12:13.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: s3transfer -Version: 0.19.2 +Version: 0.19.3 Summary: An Amazon S3 Transfer Manager Home-page: https://github.com/boto/s3transfer Author: Amazon Web Services diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3transfer-0.19.2/tests/functional/test_upload.py new/s3transfer-0.19.3/tests/functional/test_upload.py --- old/s3transfer-0.19.2/tests/functional/test_upload.py 2026-07-22 20:02:00.000000000 +0200 +++ new/s3transfer-0.19.3/tests/functional/test_upload.py 2026-10-19 20:12:13.000000000 +0200 @@ -564,6 +564,20 @@ self.assert_expected_client_calls_were_correct() self.assert_upload_part_bodies_were_correct() + def test_multipart_upload_with_negative_read_size(self): + self.add_create_multipart_response_with_default_expected_params() + self.add_upload_part_responses_with_default_expected_params() + self.add_complete_multipart_response_with_default_expected_params() + + with mock.patch.object( + self, '_stream_body', side_effect=lambda body: body.read(-1) + ): + future = self.manager.upload(self.filename, self.bucket, self.key) + future.result() + + self.assert_expected_client_calls_were_correct() + self.assert_upload_part_bodies_were_correct() + def test_limits_in_memory_chunks_for_fileobj(self): # Limit the maximum in memory chunks to one but make number of # threads more than one. This means that the upload will have to diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3transfer-0.19.2/tests/unit/test_s3transfer.py new/s3transfer-0.19.3/tests/unit/test_s3transfer.py --- old/s3transfer-0.19.2/tests/unit/test_s3transfer.py 2026-07-22 20:02:00.000000000 +0200 +++ new/s3transfer-0.19.3/tests/unit/test_s3transfer.py 2026-10-19 20:12:13.000000000 +0200 @@ -133,6 +133,47 @@ def tearDown(self): shutil.rmtree(self.tempdir) + def test_read_negative_amount_stays_within_chunk(self): + filename = os.path.join(self.tempdir, 'foo') + with open(filename, 'wb') as f: + f.write(b'beforechunkafter') + for amount in (-1, -2): + with self.subTest(amount=amount): + amounts_seen = [] + with ReadFileChunk.from_filename( + filename, + start_byte=6, + chunk_size=5, + callback=amounts_seen.append, + ) as chunk: + self.assertEqual(chunk.read(2), b'ch') + self.assertEqual(chunk.read(amount), b'unk') + self.assertEqual(chunk.tell(), 5) + self.assertEqual(chunk.read(amount), b'') + self.assertEqual(sum(amounts_seen), 5) + + def test_read_after_seek_past_chunk_returns_empty(self): + filename = os.path.join(self.tempdir, 'foo') + with open(filename, 'wb') as f: + f.write(b'beforechunkafter') + for amount in (None, -1, -2, 0, 1): + with self.subTest(amount=amount): + amounts_seen = [] + with ReadFileChunk.from_filename( + filename, + start_byte=6, + chunk_size=5, + callback=amounts_seen.append, + ) as chunk: + chunk.seek(6) + self.assertEqual(chunk.read(amount), b'') + self.assertEqual(chunk.tell(), 6) + self.assertEqual(amounts_seen, [6, 0]) + chunk.seek(0) + self.assertEqual(chunk.read(), b'chunk') + self.assertEqual(chunk.tell(), 5) + self.assertEqual(amounts_seen, [6, 0, -6, 5]) + def test_read_entire_chunk(self): filename = os.path.join(self.tempdir, 'foo') with open(filename, 'wb') as f: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s3transfer-0.19.2/tests/unit/test_utils.py new/s3transfer-0.19.3/tests/unit/test_utils.py --- old/s3transfer-0.19.2/tests/unit/test_utils.py 2026-07-22 20:02:00.000000000 +0200 +++ new/s3transfer-0.19.3/tests/unit/test_utils.py 2026-10-19 20:12:13.000000000 +0200 @@ -459,6 +459,29 @@ class TestReadFileChunk(BaseUtilsTest): + def test_read_negative_amount_stays_within_chunk(self): + filename = os.path.join(self.tempdir, 'foo') + with open(filename, 'wb') as f: + f.write(b'beforechunkafter') + for amount in (-1, -2): + with self.subTest(amount=amount): + amounts_seen = [] + with ReadFileChunk.from_filename( + filename, + start_byte=6, + chunk_size=5, + callbacks=[ + lambda bytes_transferred: amounts_seen.append( + bytes_transferred + ) + ], + ) as chunk: + self.assertEqual(chunk.read(2), b'ch') + self.assertEqual(chunk.read(amount), b'unk') + self.assertEqual(chunk.tell(), 5) + self.assertEqual(chunk.read(amount), b'') + self.assertEqual(sum(amounts_seen), 5) + def test_read_entire_chunk(self): filename = os.path.join(self.tempdir, 'foo') with open(filename, 'wb') as f:
