From 53644b34b78808ca00a0c7640ea28f2f9cd62734 Mon Sep 17 00:00:00 2001 From: sjh9714 <163989462+sjh9714@users.noreply.github.com> Date: Thu, 9 Jul 2026 00:31:58 +0900 Subject: [PATCH] fix(python): add collection close method --- python/tests/detail/test_collection_open.py | 40 +++++++++++++-------- python/zvec/model/collection.py | 6 ++++ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/python/tests/detail/test_collection_open.py b/python/tests/detail/test_collection_open.py index 2d6c38ae4..987f8a30e 100644 --- a/python/tests/detail/test_collection_open.py +++ b/python/tests/detail/test_collection_open.py @@ -108,6 +108,23 @@ def test_collection( class TestCollectionOpen: + def test_close_releases_collection_for_reopen( + self, tmp_path_factory, collection_schema, collection_option + ): + temp_dir = tmp_path_factory.mktemp("zvec") + collection_path = temp_dir / "test_collection" + collection_path_str = str(collection_path) + + created_coll = zvec.create_and_open( + path=collection_path_str, schema=collection_schema, option=collection_option + ) + + created_coll.close() + + opened_coll = zvec.open(path=collection_path_str, option=collection_option) + assert opened_coll.path == collection_path_str + opened_coll.destroy() + def test_open_basic_functionality( self, tmp_path_factory, collection_schema, collection_option ): @@ -818,8 +835,9 @@ def test_open_concurrent_same_path(self, tmp_path_factory): def open_collection_thread(thread_id): try: coll = zvec.open(path=str(collection_path), option=collection_option) + collection_path_result = coll.path with lock: - results.append((thread_id, coll)) + results.append((thread_id, collection_path_result)) # Close the collection if opened successfully if hasattr(coll, "close") and coll is not None: coll.close() @@ -847,23 +865,15 @@ def open_collection_thread(thread_id): ) # Additional verification: check that the successful open has a valid collection - successful_thread_id, successful_collection = results[0] - assert successful_collection is not None, ( + _, successful_collection_path = results[0] + assert successful_collection_path is not None, ( "Successful open should return a valid collection" ) - assert successful_collection.path == str(collection_path), ( - "Collection path mismatch" - ) + assert successful_collection_path == str(collection_path), "Collection path mismatch" - # Clean up the successfully opened collection - if ( - hasattr(successful_collection, "destroy") - and successful_collection is not None - ): - try: - successful_collection.destroy() - except Exception as e: - print(f"Warning: failed to destroy collection: {e}") + # Clean up after the successful worker released its collection handle. + cleanup_coll = zvec.open(path=str(collection_path), option=collection_option) + cleanup_coll.destroy() def test_open_with_corrupted_files(self, tmp_path_factory): # First create a collection diff --git a/python/zvec/model/collection.py b/python/zvec/model/collection.py index b90caae94..04968b0a5 100644 --- a/python/zvec/model/collection.py +++ b/python/zvec/model/collection.py @@ -56,6 +56,12 @@ def __init__(self, obj: _Collection): self._schema = None self._querier = None + def close(self) -> None: + """Release the underlying collection handle.""" + self._obj = None + self._schema = None + self._querier = None + @classmethod def _from_core(cls, core_collection: _Collection) -> Collection: if not core_collection: