From 13df747f180da94c3a487067e2a8cec8839a5158 Mon Sep 17 00:00:00 2001 From: Preston Zhao Date: Thu, 22 Oct 2026 13:43:36 -0500 Subject: [PATCH] fix(python): return the session supplied to LanceDBConnection (#4433) LanceDBConnection.session read AsyncConnection.session, but AsyncConnection has no session attribute, so access raised AttributeError. Store the session passed to the constructor and return that object. Assisted by Cursor (Grok). Co-authored-by: Preston Zhao <195942578+canyang25@users.noreply.github.com> --- python/python/lancedb/db.py | 11 ++++++++++- python/python/tests/test_db.py | 3 +++ python/python/tests/test_session.py | 10 ++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/python/python/lancedb/db.py b/python/python/lancedb/db.py index e1e5d270a..a74763afb 100644 --- a/python/python/lancedb/db.py +++ b/python/python/lancedb/db.py @@ -1300,6 +1300,10 @@ class LanceDBConnection(DBConnection): self.storage_options = storage_options self._manifest_enabled = manifest_enabled self._namespace_client_properties = namespace_client_properties + # The native connection does not expose the Python Session wrapper. + # Keep the object supplied by the caller so this property stays + # synchronous for debugger inspection. + self._session = session if _inner is not None: self._conn = _inner # Native-derived wrappers resolve this in their async reconstruction @@ -1366,7 +1370,12 @@ class LanceDBConnection(DBConnection): @property def session(self) -> Optional[Session]: - return self._conn.session + """Return the session supplied when this connection was opened. + + None when the caller did not pass a session, including connections + reconstructed with :meth:`from_inner`. + """ + return self._session @property def uri(self) -> str: diff --git a/python/python/tests/test_db.py b/python/python/tests/test_db.py index 7d37910a3..af63987aa 100644 --- a/python/python/tests/test_db.py +++ b/python/python/tests/test_db.py @@ -86,6 +86,7 @@ def test_sync_debugger_inspection_does_not_use_background_loop(tmp_path, monkeyp assert members["uri"] == str(tmp_path) assert members["read_consistency_interval"] is None + assert members["session"] is None assert repr(db) == f"LanceDBConnection(uri={str(tmp_path)!r})" assert repr(table) == f"LanceTable(name='test', _conn={db!r})" @@ -105,6 +106,8 @@ def test_read_consistency_interval_does_not_use_background_loop(tmp_path, monkey assert db.read_consistency_interval == consistency_interval assert db_from_inner.read_consistency_interval == consistency_interval + assert db.session is None + assert db_from_inner.session is None def test_ingest_pd(tmp_path): diff --git a/python/python/tests/test_session.py b/python/python/tests/test_session.py index 8923477c7..d0bc54210 100644 --- a/python/python/tests/test_session.py +++ b/python/python/tests/test_session.py @@ -36,3 +36,13 @@ def test_session_cache_configuration(tmp_path): assert final_cache_size > initial_cache_size # Cache should have grown assert final_cache_items >= initial_cache_items # Items should not decrease assert initial_cache_size < index_cache_size + metadata_cache_size + + +def test_connection_session_returns_supplied_session(tmp_path): + """Sync connections must expose the session they were opened with.""" + db = lancedb.connect(tmp_path) + assert db.session is None + + session = lancedb.Session() + db = lancedb.connect(tmp_path, session=session) + assert db.session is session