From 7e0ebd134516655537185f137015eceef22d2cc1 Mon Sep 17 00:00:00 2001 From: Ahnaf Shahriar Date: Mon, 24 Aug 2026 12:28:48 -0400 Subject: [PATCH] Recognise the engine wheel's real layout maturin ships the Rust engine as a package: simantic_rust/__init__.py beside simantic_rust/simantic_rust.abi3.so. is_rust_engine only matched a flat simantic_rust., so it returned False for every wheel we would actually publish. That failed quietly in the worst way. Importing still worked, because putting the directory on sys.path imports the package either way, so a first run looked fine. But installed_rust_engine() never found the managed copy, so every new process re-downloaded the wheel instead of reusing ~/.simantic/engine-rust. Accept either shape, since the only thing that matters is whether the module imports. Found by building the wheel with maturin and unpacking it rather than by reasoning about what it should contain; the tests pin both layouts and the directory that has neither. --- src/simantic/install.py | 17 ++++++++++++++++- tests/test_install.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/simantic/install.py b/src/simantic/install.py index 40be34f..2509d12 100644 --- a/src/simantic/install.py +++ b/src/simantic/install.py @@ -302,7 +302,22 @@ def rust_engine_root() -> Path: def is_rust_engine(d: Path) -> bool: - return d.is_dir() and any(p.name.startswith("simantic_rust.") for p in d.iterdir()) + """True when `d` holds an importable `simantic_rust`. + + maturin ships the extension as a package: `simantic_rust/__init__.py` + beside `simantic_rust/simantic_rust.abi3.so`. A bare `simantic_rust.` + laid out flat is equally importable. Accept either, because the only thing + that matters here is whether putting `d` on `sys.path` makes the module + import; matching one layout silently re-downloaded the engine on every + process, since the managed copy was never recognised. + """ + if not d.is_dir(): + return False + return any( + p.name.startswith("simantic_rust.") + or (p.name == "simantic_rust" and (p / "__init__.py").exists()) + for p in d.iterdir() + ) def installed_rust_engine() -> Path | None: diff --git a/tests/test_install.py b/tests/test_install.py index 5ef9f05..8bc2bd9 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -434,3 +434,32 @@ def capture(request, **k): with pytest.raises(install.InstallError): install.fetch_rust_manifest() assert seen[0].endswith("/pyrite/latest.json") + + +# -- engine layouts ---------------------------------------------------------- +# +# maturin ships the Rust engine as a package, not a bare .so. Recognising only +# the flat shape looked harmless (the import still worked once the directory was +# on sys.path) but meant the managed copy was never found, so every process +# re-downloaded the wheel. + + +def test_a_maturin_package_layout_is_recognised(tmp_path): + """What `maturin build` actually produces, verified against a real wheel.""" + pkg = tmp_path / "simantic_rust" + pkg.mkdir() + (pkg / "__init__.py").write_text("from .simantic_rust import *\n") + (pkg / "simantic_rust.abi3.so").write_bytes(b"\x7fELF") + (tmp_path / "simantic_rust-0.3.0.dist-info").mkdir() + assert install.is_rust_engine(tmp_path) + + +def test_a_flat_extension_is_recognised(tmp_path): + (tmp_path / "simantic_rust.abi3.so").write_bytes(b"\x7fELF") + assert install.is_rust_engine(tmp_path) + + +def test_a_directory_without_the_module_is_not(tmp_path): + (tmp_path / "simantic_rust-0.3.0.dist-info").mkdir() + (tmp_path / "simantic_rust").mkdir() # no __init__.py: not importable + assert not install.is_rust_engine(tmp_path)