From 27dd92c67ebee5bbc37c0d085427d78fc2ffcd87 Mon Sep 17 00:00:00 2001 From: "lancedb-gatefixer[bot]" <313497061+lancedb-gatefixer[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 16:36:27 +0800 Subject: [PATCH] test(python): cover debugger-safe connection inspection (#3880) ## Summary - expand the synchronous debugger regression to enumerate every exposed connection attribute while the Python background loop is unavailable - retain direct representation checks for connections and tables ## Root cause VS Code debugpy suspends Python threads at a breakpoint and inspects local variables. Connection representation and property access previously dispatched asynchronous work to LanceDBBackgroundEventLoop and waited for the suspended loop thread, deadlocking the debugger. The production safeguards landed in #3620 and #3788; this regression exercises debugger-style whole-object expansion so a newly exposed property cannot reintroduce the original failure. ## Validation - uv run --no-sync pytest python/tests/test_db.py::test_sync_debugger_inspection_does_not_use_background_loop python/tests/test_db.py::test_read_consistency_interval_does_not_use_background_loop -q (2 passed) - uv run --no-sync pytest python/tests/test_db.py -q (48 passed) - python/.venv/bin/ruff format --check python/python/tests/test_db.py - python/.venv/bin/ruff check . - git diff --check Fixes #3611 Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com> --- python/python/tests/test_db.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/python/python/tests/test_db.py b/python/python/tests/test_db.py index 93b791650..8f4a8850c 100644 --- a/python/python/tests/test_db.py +++ b/python/python/tests/test_db.py @@ -2,6 +2,7 @@ # SPDX-FileCopyrightText: Copyright The LanceDB Authors +import inspect import re import sys from datetime import timedelta @@ -62,17 +63,23 @@ def test_basic(tmp_path): assert db.open_table("test").name == db["test"].name -def test_sync_repr_does_not_use_background_loop(tmp_path, monkeypatch): +def test_sync_debugger_inspection_does_not_use_background_loop(tmp_path, monkeypatch): from lancedb.background_loop import LOOP db = lancedb.connect(tmp_path) table = db.create_table("test", data=[{"id": 1}]) def fail_run(*args, **kwargs): - raise AssertionError("repr should not use the Python background loop") + raise AssertionError("debugger inspection should not use the background loop") monkeypatch.setattr(LOOP, "run", fail_run) + # Debuggers enumerate and evaluate every exposed attribute when expanding a + # variable. This must remain safe while their breakpoint suspends LOOP's thread. + members = dict(inspect.getmembers(db)) + + assert members["uri"] == str(tmp_path) + assert members["read_consistency_interval"] is None assert repr(db) == f"LanceDBConnection(uri={str(tmp_path)!r})" assert repr(table) == f"LanceTable(name='test', _conn={db!r})"