Skip to content

Commit e45d46e

Browse files
robert3005claude
andcommitted
Raise each VortexErrorKind as its Python exception class
The Python bindings turned every VortexError into RuntimeError, so none of the kinds reached Python, where they were designed to mean something: a caller could not catch an IndexError or a KeyError, because there was never one to catch. Each kind now raises the exception it is the analogue of: OutOfBounds IndexError NotFound KeyError Overflow OverflowError InvalidArgument ValueError Serde ValueError MismatchedTypes TypeError NotImplemented NotImplementedError AssertionFailed AssertionError Io OSError Other RuntimeError The one test that asserted RuntimeError was checking that an unserializable expression reports clearly; it now expects the NotImplementedError that operation raises. Signed-off-by: Robert Kruszewski <github@robertk.io> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S7EtMqoZ91rrCCh9vS2yTm
1 parent 2087482 commit e45d46e

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

‎vortex-python/src/error.rs‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,17 @@
33

44
use pyo3::CastError;
55
use pyo3::PyErr;
6+
use pyo3::exceptions::PyAssertionError;
7+
use pyo3::exceptions::PyIndexError;
8+
use pyo3::exceptions::PyKeyError;
9+
use pyo3::exceptions::PyNotImplementedError;
10+
use pyo3::exceptions::PyOSError;
11+
use pyo3::exceptions::PyOverflowError;
612
use pyo3::exceptions::PyRuntimeError;
13+
use pyo3::exceptions::PyTypeError;
14+
use pyo3::exceptions::PyValueError;
715
use vortex::error::VortexError;
16+
use vortex::error::VortexErrorKind;
817

918
/// Error type to merge [`VortexError`] and [`PyErr`].
1019
pub enum PyVortexError {
@@ -37,7 +46,24 @@ impl From<PyVortexError> for PyErr {
3746
fn from(value: PyVortexError) -> Self {
3847
match value {
3948
PyVortexError::Py(py) => py,
40-
PyVortexError::Vortex(vx) => PyRuntimeError::new_err(vx.to_string()),
49+
PyVortexError::Vortex(vx) => vortex_to_py_err(vx),
4150
}
4251
}
4352
}
53+
54+
/// Raises a [`VortexError`] as the Python exception its kind is the analogue of.
55+
fn vortex_to_py_err(error: VortexError) -> PyErr {
56+
let message = error.to_string();
57+
match error.kind() {
58+
VortexErrorKind::OutOfBounds => PyIndexError::new_err(message),
59+
VortexErrorKind::NotFound => PyKeyError::new_err(message),
60+
VortexErrorKind::Overflow => PyOverflowError::new_err(message),
61+
VortexErrorKind::InvalidArgument | VortexErrorKind::Serde => PyValueError::new_err(message),
62+
VortexErrorKind::NotImplemented => PyNotImplementedError::new_err(message),
63+
VortexErrorKind::MismatchedTypes => PyTypeError::new_err(message),
64+
VortexErrorKind::AssertionFailed => PyAssertionError::new_err(message),
65+
VortexErrorKind::Io => PyOSError::new_err(message),
66+
// `Other`, and any kind added after this binding was written.
67+
_ => PyRuntimeError::new_err(message),
68+
}
69+
}

‎vortex-python/test/test_expr.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def test_builder_round_trips_through_proto(name: str) -> None:
115115

116116
@pytest.mark.parametrize("name", sorted(NOT_SERIALIZABLE))
117117
def test_unserializable_builder_reports_clearly(name: str) -> None:
118-
with pytest.raises(RuntimeError, match="serial"):
118+
with pytest.raises(NotImplementedError, match="serial"):
119119
_ = BUILDERS[name]().serialize()
120120

121121

0 commit comments

Comments
 (0)