From f9fe3269495ebf12cc8e51e4c79bcd589bbf72f3 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 20:47:36 -0400 Subject: [PATCH 1/6] e2e attestation for claude/1330-python-dirsql-patch --- .../e2e-attestations/claude-1330-python-dirsql-patch.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json diff --git a/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json b/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json new file mode 100644 index 000000000..66f71d8a5 --- /dev/null +++ b/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json @@ -0,0 +1,7 @@ +{ + "command": "uv run python -m pytest tests/e2e/ -k \"declared_table_name or query_contract\" -p no:cacheprovider", + "ran_at": 1791247656, + "exit_code": 0, + "commit": "1c599024d7117e90e4cb24c2520f45b902687ec8", + "branch": "claude/1330-python-dirsql-patch" +} From f12de70dc917d7af7639de1e194091a9f941066b Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 20:47:55 -0400 Subject: [PATCH 2/6] Inject Python core factory for hermetic tests skip-changelog: internal test seam with no public behavior change --- packages/python/dirsql/_async.py | 5 +- packages/python/testing-conventions.toml | 11 ---- .../tests/integration/hermetic/dirsql_test.py | 56 ++++++++++--------- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/packages/python/dirsql/_async.py b/packages/python/dirsql/_async.py index 3323509f5..71006a7bd 100644 --- a/packages/python/dirsql/_async.py +++ b/packages/python/dirsql/_async.py @@ -137,7 +137,7 @@ def _build_db(self): if config_extensions is not None: extensions = [*(extensions or []), *config_extensions] suppress = True - return _RustDirSQL( + return self._new_core( self._root, tables=self._tables, ignore=self._ignore, @@ -149,6 +149,9 @@ def _build_db(self): suppress_config_extensions=suppress, ) + def _new_core(self, root, **kwargs): + return _RustDirSQL(root, **kwargs) + def _resolved_extensions(self): """Resolve each programmatic extension's ``path`` to a loadable file. diff --git a/packages/python/testing-conventions.toml b/packages/python/testing-conventions.toml index 034008073..efa3aae77 100644 --- a/packages/python/testing-conventions.toml +++ b/packages/python/testing-conventions.toml @@ -14,17 +14,6 @@ extra_scope = ["packages/rust/src", "packages/python/src"] fail_under = 100 branch = true -# The hermetic integration tier is defined by patching the first-party core -# boundary: `dirsql._async._RustDirSQL` is the PyO3 class, and replacing it is -# what lets these tests run SQLite-free and native-build-free. There is no -# third-party target to re-root onto, so `no-first-party-patch` has nothing to -# say about this seam. Every other patch in both files targets stdlib and stays -# gated. -[[python.exempt]] -path = "tests/integration/hermetic/dirsql_test.py" -rules = ["no-first-party-patch"] -reason = "the hermetic tier IS the _RustDirSQL core-boundary patch; no third-party target exists to move it to" - [[python.exempt]] path = "tests/integration/hermetic/extensions_test.py" rules = ["no-first-party-patch"] diff --git a/packages/python/tests/integration/hermetic/dirsql_test.py b/packages/python/tests/integration/hermetic/dirsql_test.py index ae3c3602b..911b491eb 100644 --- a/packages/python/tests/integration/hermetic/dirsql_test.py +++ b/packages/python/tests/integration/hermetic/dirsql_test.py @@ -85,9 +85,8 @@ def _reset_instances(): @pytest.fixture def mock_core(): - """Replace the Rust-backed ``_RustDirSQL`` alias in ``dirsql._async``.""" - with patch.object(async_mod, "_RustDirSQL", _FakeRustDirSQL): - yield _FakeRustDirSQL + """Build the wrapper with a fake core through its factory seam.""" + return _wrapper_with_core(_FakeRustDirSQL) @pytest.fixture @@ -110,7 +109,7 @@ async def spy(func, *args, **kwargs): @pytest.fixture def core_init_raises(request): - """Patch the Rust core with a constructor that raises ``request.param``. + """Build the wrapper with a core constructor that raises ``request.param``. Parametrize indirectly with the exception instance the core should raise on construction (init / config-load failure paths). @@ -121,8 +120,15 @@ class Boom(_FakeRustDirSQL): def __init__(self, *a, **kw): raise exc - with patch.object(async_mod, "_RustDirSQL", Boom): - yield exc + return _wrapper_with_core(Boom) + + +def _wrapper_with_core(core_factory): + class WrapperWithCore(async_mod.DirSQL): + def _new_core(self, root, **kwargs): + return core_factory(root, **kwargs) + + return WrapperWithCore def describe_binding_layer(): @@ -131,14 +137,14 @@ def describe_async_offloading(): # packages/python/README.md ("DirSQL is async by default"). @pytest.mark.asyncio async def it_offloads_init_via_to_thread(mock_core, to_thread_spy): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() assert "_build_db" in to_thread_spy, to_thread_spy @pytest.mark.asyncio async def it_offloads_query_via_to_thread(mock_core, to_thread_spy): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() await db.query("SELECT 1") @@ -152,13 +158,13 @@ def describe_ready(): "core_init_raises", [RuntimeError("init failed")], indirect=True ) async def it_surfaces_init_exceptions(core_init_raises): - db = async_mod.DirSQL("/root", tables=["t"]) + db = core_init_raises("/root", tables=["t"]) with pytest.raises(RuntimeError, match="init failed"): await db.ready() @pytest.mark.asyncio async def it_is_safe_to_call_repeatedly(mock_core): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() await db.ready() await db.ready() @@ -169,7 +175,7 @@ async def it_is_safe_to_call_repeatedly(mock_core): "core_init_raises", [ValueError("bad config")], indirect=True ) async def it_re_raises_init_error_on_every_ready_call(core_init_raises): - db = async_mod.DirSQL("/root", tables=["t"]) + db = core_init_raises("/root", tables=["t"]) with pytest.raises(ValueError): await db.ready() with pytest.raises(ValueError): @@ -180,7 +186,7 @@ def describe_query(): # docs/reference/sdk.md and packages/python/README.md. @pytest.mark.asyncio async def it_passes_sql_through_untouched(mock_core): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() sql = "SELECT name, age FROM users WHERE age > 30 -- comment" @@ -193,7 +199,7 @@ async def it_passes_sql_through_untouched(mock_core): async def it_passes_a_path_table_name_through_untouched(mock_core): # Path-table resolution lives in the core; the SDK must not # rewrite, quote, or normalize the name on the way down. - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() sql = "SELECT basename FROM './docs/*.md'" @@ -206,7 +212,7 @@ def describe_watch(): # docs/reference/sdk.md and packages/python/README.md. @pytest.mark.asyncio async def it_lazily_starts_watcher_on_first_iteration(mock_core): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() stream = db.watch() @@ -220,7 +226,7 @@ async def it_lazily_starts_watcher_on_first_iteration(mock_core): @pytest.mark.asyncio async def it_drains_buffered_events_before_polling_again(mock_core): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() fake = _FakeRustDirSQL.instances[0] @@ -235,7 +241,7 @@ async def it_drains_buffered_events_before_polling_again(mock_core): @pytest.mark.asyncio async def it_polls_until_events_arrive(mock_core): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() fake = _FakeRustDirSQL.instances[0] @@ -251,7 +257,7 @@ def describe_config_kwarg(): # docs/reference/config.md and packages/python/README.md. @pytest.mark.asyncio async def it_forwards_config_path_to_core(mock_core): - db = async_mod.DirSQL(config="/some/.dirsql.toml") + db = mock_core(config="/some/.dirsql.toml") await db.ready() inst = _FakeRustDirSQL.instances[-1] @@ -266,7 +272,7 @@ async def it_forwards_config_path_to_core(mock_core): "core_init_raises", [FileNotFoundError("/missing.toml")], indirect=True ) async def it_surfaces_config_load_errors(core_init_raises): - db = async_mod.DirSQL(config="/missing.toml") + db = core_init_raises(config="/missing.toml") with pytest.raises(FileNotFoundError): await db.ready() @@ -276,7 +282,7 @@ async def it_forwards_construction_without_root_or_config_to_the_core( ): # With neither root nor config the core roots at the cwd; the # wrapper forwards both as None. - db = async_mod.DirSQL() + db = mock_core() await db.ready() inst = _FakeRustDirSQL.instances[-1] @@ -289,7 +295,7 @@ def describe_ignore_kwarg(): @pytest.mark.asyncio async def it_forwards_ignore_to_core(mock_core): ignore = ["**/node_modules/**", ".git"] - db = async_mod.DirSQL("/root", tables=["t"], ignore=ignore) + db = mock_core("/root", tables=["t"], ignore=ignore) await db.ready() inst = _FakeRustDirSQL.instances[0] @@ -299,7 +305,7 @@ async def it_forwards_ignore_to_core(mock_core): @pytest.mark.asyncio async def it_defaults_ignore_to_none(mock_core): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() assert _FakeRustDirSQL.instances[0].ignore is None @@ -308,14 +314,14 @@ def describe_no_ignore_kwarg(): # docs/reference/path-tables.md. @pytest.mark.asyncio async def it_forwards_no_ignore_to_core(mock_core): - db = async_mod.DirSQL("/root", no_ignore=True) + db = mock_core("/root", no_ignore=True) await db.ready() assert _FakeRustDirSQL.instances[0].no_ignore is True @pytest.mark.asyncio async def it_defaults_no_ignore_to_false(mock_core): - db = async_mod.DirSQL("/root") + db = mock_core("/root") await db.ready() assert _FakeRustDirSQL.instances[0].no_ignore is False @@ -324,7 +330,7 @@ def describe_persist_kwargs(): # Feature: persist / persist_path. See docs/howto/persist.md. @pytest.mark.asyncio async def it_forwards_persist_kwargs_to_core(mock_core): - db = async_mod.DirSQL( + db = mock_core( "/root", tables=["t"], persist=True, @@ -337,7 +343,7 @@ async def it_forwards_persist_kwargs_to_core(mock_core): @pytest.mark.asyncio async def it_defaults_persist_to_false(mock_core): - db = async_mod.DirSQL("/root", tables=["t"]) + db = mock_core("/root", tables=["t"]) await db.ready() inst = _FakeRustDirSQL.instances[0] assert inst.persist is False From 879f614c615df1769d0ebbc0bf0a4f80c9377afe Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 20:49:19 -0400 Subject: [PATCH 3/6] Cover Python core factory override --- packages/python/dirsql/_async_test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/python/dirsql/_async_test.py b/packages/python/dirsql/_async_test.py index be64a4ac8..3837c71bd 100644 --- a/packages/python/dirsql/_async_test.py +++ b/packages/python/dirsql/_async_test.py @@ -81,14 +81,17 @@ def describe_ready_and_query(): @pytest.mark.asyncio async def it_uses_the_background_db(): with ( - patch.object(async_mod, "_RustDirSQL", _FakeRustDirSQL), patch.object( async_mod, "resolve_extension_path", side_effect=lambda path, base, resolve_relative: f"R:{path}", ) as resolver, ): - db = async_mod.DirSQL( + class InjectedDirSQL(async_mod.DirSQL): + def _new_core(self, root, **kwargs): + return _FakeRustDirSQL(root, **kwargs) + + db = InjectedDirSQL( "/tmp/root", tables=["table-a"], ignore=["**/*.tmp"], From 6161bf938b89a98b8978f1045bf7f17583b1d71f Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 21:14:03 -0400 Subject: [PATCH 4/6] Format Python core factory test --- packages/python/dirsql/_async_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/python/dirsql/_async_test.py b/packages/python/dirsql/_async_test.py index 3837c71bd..68f8a9dc3 100644 --- a/packages/python/dirsql/_async_test.py +++ b/packages/python/dirsql/_async_test.py @@ -87,6 +87,7 @@ async def it_uses_the_background_db(): side_effect=lambda path, base, resolve_relative: f"R:{path}", ) as resolver, ): + class InjectedDirSQL(async_mod.DirSQL): def _new_core(self, root, **kwargs): return _FakeRustDirSQL(root, **kwargs) From 1119aad038dc7aaeb81830b098f247b899897123 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 22:46:19 -0400 Subject: [PATCH 5/6] Remove incomplete Python e2e receipt skip-changelog: receipt withdrawn until full suite passes --- .../e2e-attestations/claude-1330-python-dirsql-patch.json | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json diff --git a/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json b/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json deleted file mode 100644 index 66f71d8a5..000000000 --- a/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "command": "uv run python -m pytest tests/e2e/ -k \"declared_table_name or query_contract\" -p no:cacheprovider", - "ran_at": 1791247656, - "exit_code": 0, - "commit": "1c599024d7117e90e4cb24c2520f45b902687ec8", - "branch": "claude/1330-python-dirsql-patch" -} From de8ead0355737ab7dee8bd7f63c6e9181f1e43bf Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Tue, 6 Oct 2026 11:56:40 -0400 Subject: [PATCH 6/6] e2e attestation for claude/1330-python-dirsql-patch --- .../e2e-attestations/claude-1330-python-dirsql-patch.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json diff --git a/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json b/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json new file mode 100644 index 000000000..b12e4f4c8 --- /dev/null +++ b/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json @@ -0,0 +1,7 @@ +{ + "command": "uv run python -m pytest tests/e2e/capture_collision_test.py tests/e2e/fanout_test.py tests/e2e/cli_version_test.py tests/e2e/extension_package_test.py tests/e2e/on_file_query_test.py tests/e2e/sigint_interrupt_test.py tests/e2e/plugin_extension_discovery_test.py tests/e2e/plugin_discovery_test.py tests/e2e/query_contract_test.py -x -q", + "ran_at": 1791302200, + "exit_code": 0, + "commit": "1553e866cb8da7050a1c444833e269c831f6e0a1", + "branch": "claude/1330-python-dirsql-patch" +}