py: only well-formed masks are NotImplementedError; others stay TypeError
A boolean array of the axis's length, or of the dataset's whole shape, is a mask h5py would apply (NotImplementedError here); one of any other shape (np.array(True), a wrong length) is a key h5py itself refuses with TypeError, which test_errors_match_h5py requires us to match. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -255,6 +255,17 @@ pub(crate) fn parse(key: &Bound<'_, PyAny>, dims: &[u64]) -> PyResult<Plan> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A mask of the dataset's whole shape (`ds[ds[()] > 0]`).
|
||||||
|
if let [a] = args.as_slice() {
|
||||||
|
let np = key.py().import("numpy")?;
|
||||||
|
if a.is_instance(&np.getattr("ndarray")?)?
|
||||||
|
&& a.getattr("dtype")?.getattr("kind")?.extract::<String>()? == "b"
|
||||||
|
&& a.getattr("ndim")?.extract::<usize>()? > 1
|
||||||
|
&& a.getattr("shape")?.extract::<Vec<u64>>()? == dims
|
||||||
|
{
|
||||||
|
return Err(mask_unsupported());
|
||||||
|
}
|
||||||
|
}
|
||||||
if args.iter().any(|a| a.is_none()) {
|
if args.iter().any(|a| a.is_none()) {
|
||||||
return Err(PyTypeError::new_err(
|
return Err(PyTypeError::new_err(
|
||||||
"Indexing with None (or np.newaxis) is not supported",
|
"Indexing with None (or np.newaxis) is not supported",
|
||||||
@@ -333,6 +344,10 @@ pub(crate) fn parse(key: &Bound<'_, PyAny>, dims: &[u64]) -> PyResult<Plan> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mask_unsupported() -> PyErr {
|
||||||
|
PyNotImplementedError::new_err("boolean mask indexing is not supported by clawhdf5")
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_axis(py: Python<'_>, a: &Bound<'_, PyAny>, n: u64) -> PyResult<Axis> {
|
fn parse_axis(py: Python<'_>, a: &Bound<'_, PyAny>, n: u64) -> PyResult<Axis> {
|
||||||
if a.is_none() {
|
if a.is_none() {
|
||||||
return Err(PyTypeError::new_err(
|
return Err(PyTypeError::new_err(
|
||||||
@@ -380,10 +395,15 @@ fn parse_axis(py: Python<'_>, a: &Bound<'_, PyAny>, n: u64) -> PyResult<Axis> {
|
|||||||
let arr = np.call_method1("asarray", (a,))?;
|
let arr = np.call_method1("asarray", (a,))?;
|
||||||
let kind: String = arr.getattr("dtype")?.getattr("kind")?.extract()?;
|
let kind: String = arr.getattr("dtype")?.getattr("kind")?.extract()?;
|
||||||
if kind == "b" {
|
if kind == "b" {
|
||||||
// h5py supports masks; clawhdf5 does not (yet), for reads or
|
// A mask along this axis (h5py supports them; clawhdf5 does
|
||||||
// writes: an unsupported operation, not a wrong key.
|
// not, for reads or writes: an unsupported operation). A mask
|
||||||
return Err(PyNotImplementedError::new_err(
|
// of any other shape is a wrong key, as in h5py.
|
||||||
"boolean mask indexing is not supported by clawhdf5",
|
let shape: Vec<u64> = arr.getattr("shape")?.extract()?;
|
||||||
|
if shape == [n] {
|
||||||
|
return Err(mask_unsupported());
|
||||||
|
}
|
||||||
|
return Err(PyTypeError::new_err(
|
||||||
|
"Boolean indexing array has incompatible shape",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let ndim: usize = arr.getattr("ndim")?.extract()?;
|
let ndim: usize = arr.getattr("ndim")?.extract()?;
|
||||||
|
|||||||
Reference in New Issue
Block a user