mirror of
https://github.com/lancedb/lancedb.git
synced 2026-11-13 14:16:54 +00:00
test(python): load checked-in error classes for Rust tests (#4876)
Bare Rust test runners do not install the `lancedb` Python package, so the typed-error tests fail with `ModuleNotFoundError`. Load the checked-in exception modules once for the embedded interpreter, preserving exception-class identity across parallel tests and the existing type/cause assertions. Rust CI now watches the binding sources and the Python exception modules embedded by these tests, so those changes exercise the macOS Rust test jobs.
This commit is contained in:
@@ -14,6 +14,9 @@ on:
|
||||
- docs/web-tests/blob-v2/rs/**
|
||||
- nodejs/Cargo.toml
|
||||
- python/Cargo.toml
|
||||
- python/src/**
|
||||
- python/python/lancedb/exceptions.py
|
||||
- python/python/lancedb/remote/errors.py
|
||||
- ci/build_no_lock.py
|
||||
- ci/tests/test_build_no_lock.py
|
||||
- .github/actions/setup-protoc/**
|
||||
|
||||
+69
-4
@@ -386,16 +386,81 @@ fn is_transport_error(err: &(dyn std::error::Error + 'static)) -> bool {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
use std::ffi::CString;
|
||||
use std::sync::{Arc, Once};
|
||||
|
||||
use lancedb::error::{JobFailure, RemoteResourceIdentity};
|
||||
use pyo3::types::PyAnyMethods;
|
||||
use pyo3::types::{PyAnyMethods, PyModule};
|
||||
|
||||
use super::*;
|
||||
|
||||
static INSTALL_PYTHON_ERROR_MODULES: Once = Once::new();
|
||||
|
||||
fn install_python_error_modules(py: Python<'_>) -> PyResult<()> {
|
||||
// Load the checked-in error classes without requiring an installed wheel.
|
||||
// The namespace exception is only a base for an unrelated remote class.
|
||||
PyModule::from_code(
|
||||
py,
|
||||
c"import sys\n\nimport types\n\n\
|
||||
lancedb = types.ModuleType('lancedb')\n\
|
||||
lancedb.__path__ = []\n\
|
||||
lancedb_remote = types.ModuleType('lancedb.remote')\n\
|
||||
lancedb_remote.__path__ = []\n\
|
||||
lancedb.remote = lancedb_remote\n\
|
||||
namespace = types.ModuleType('lance_namespace')\n\
|
||||
namespace_errors = types.ModuleType('lance_namespace.errors')\n\
|
||||
namespace_errors.TableNotFoundError = RuntimeError\n\
|
||||
namespace.errors = namespace_errors\n\
|
||||
sys.modules['lancedb'] = lancedb\n\
|
||||
sys.modules['lancedb.remote'] = lancedb_remote\n\
|
||||
sys.modules['lance_namespace'] = namespace\n\
|
||||
sys.modules['lance_namespace.errors'] = namespace_errors",
|
||||
c"error_test_bootstrap.py",
|
||||
c"lancedb_error_test_bootstrap",
|
||||
)?;
|
||||
|
||||
let exceptions_code =
|
||||
CString::new(include_str!("../../python/python/lancedb/exceptions.py")).unwrap();
|
||||
let exceptions = PyModule::from_code(
|
||||
py,
|
||||
&exceptions_code,
|
||||
c"exceptions.py",
|
||||
c"lancedb.exceptions",
|
||||
)?;
|
||||
let lancedb = py.import("lancedb")?;
|
||||
lancedb.setattr("exceptions", &exceptions)?;
|
||||
py.import("sys")?
|
||||
.getattr("modules")?
|
||||
.set_item("lancedb.exceptions", &exceptions)?;
|
||||
|
||||
let remote_errors_code =
|
||||
CString::new(include_str!("../../python/python/lancedb/remote/errors.py")).unwrap();
|
||||
let remote_errors = PyModule::from_code(
|
||||
py,
|
||||
&remote_errors_code,
|
||||
c"remote/errors.py",
|
||||
c"lancedb.remote.errors",
|
||||
)?;
|
||||
lancedb
|
||||
.getattr("remote")?
|
||||
.setattr("errors", &remote_errors)?;
|
||||
py.import("sys")?
|
||||
.getattr("modules")?
|
||||
.set_item("lancedb.remote.errors", &remote_errors)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ensure_python_error_modules() {
|
||||
Python::initialize();
|
||||
// Once waits without holding the GIL; only its one-time closure attaches.
|
||||
INSTALL_PYTHON_ERROR_MODULES.call_once(|| {
|
||||
Python::attach(install_python_error_modules).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_job_failure_retains_the_named_resource_as_its_cause() {
|
||||
Python::initialize();
|
||||
ensure_python_error_modules();
|
||||
let source = LanceError::Sql {
|
||||
message: "Function 'missing' was not found".into(),
|
||||
request_id: "current-request".into(),
|
||||
@@ -515,7 +580,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn direct_catalog_lookup_is_raised_as_the_named_resource_error() {
|
||||
Python::initialize();
|
||||
ensure_python_error_modules();
|
||||
for (kind, name, namespace_path, exception) in [
|
||||
(
|
||||
"function",
|
||||
|
||||
Reference in New Issue
Block a user