From a149dfa3af68ac0c3dc6389f3083791663c11812 Mon Sep 17 00:00:00 2001 From: Zhe Chen Date: Sun, 18 Oct 2026 02:33:55 +0800 Subject: [PATCH] Fix #2200: Preserve local objects when downloading onto the source --- libcloud/storage/drivers/local.py | 2 ++ libcloud/test/storage/test_local.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/libcloud/storage/drivers/local.py b/libcloud/storage/drivers/local.py index f47d7c0649..11a128f311 100644 --- a/libcloud/storage/drivers/local.py +++ b/libcloud/storage/drivers/local.py @@ -451,6 +451,8 @@ def download_object( try: shutil.copy(obj_path, file_path) + except shutil.SameFileError: + return False except OSError: if delete_on_failure: try: diff --git a/libcloud/test/storage/test_local.py b/libcloud/test/storage/test_local.py index 7d7f271405..ea14f39ba7 100644 --- a/libcloud/test/storage/test_local.py +++ b/libcloud/test/storage/test_local.py @@ -405,6 +405,22 @@ def test_download_object_and_overwrite(self): self.remove_tmp_file(tmppath) os.unlink(destination_path) + def test_download_object_to_source_preserves_object(self): + content = b"preserve this object" + container = self.driver.create_container("same-file") + object_path = os.path.join(self.key, container.name, "object") + + for destination_path in (object_path, os.path.dirname(object_path) + os.sep): + with self.subTest(destination_path=destination_path): + obj = self.driver.upload_object_via_stream(iter([content]), container, "object") + result = self.driver.download_object(obj, destination_path, overwrite_existing=True) + self.assertFalse(result) + with open(object_path, "rb") as source: + self.assertEqual(source.read(), content) + self.assertEqual( + self.driver.get_object(container.name, "object").size, len(content) + ) + def test_download_object_as_stream_success(self): tmppath = self.make_tmp_file() container = self.driver.create_container("test6")