diff --git a/minarrow-py/src/lib.rs b/minarrow-py/src/lib.rs index 4aef44a..41e0b95 100644 --- a/minarrow-py/src/lib.rs +++ b/minarrow-py/src/lib.rs @@ -48,7 +48,7 @@ pub use chunked_array::PyChunkedArray; #[cfg(feature = "ndarray")] pub use chunked_ndarray::{PyChunkedNdArray, PyChunkedNdArrayInner}; pub use chunked_table::PyChunkedTable; -pub use convert::{build_array, resolve_index, scalar_to_py}; +pub use convert::{build_array, py_to_scalar, resolve_index, scalar_to_py}; pub use dtype::{dtype_from_arrow, width_from_arrow, DType, TypeClass}; pub use field::{PyField, PySchema}; #[cfg(feature = "ndarray")] diff --git a/pyo3/src/ffi/to_py.rs b/pyo3/src/ffi/to_py.rs index d6b25c1..f7f48ec 100644 --- a/pyo3/src/ffi/to_py.rs +++ b/pyo3/src/ffi/to_py.rs @@ -29,7 +29,7 @@ use minarrow::ffi::arrow_c_ffi::{ export_super_table_view_stream, export_to_c, export_view_to_c, ArrowArray, ArrowArrayStream, ArrowSchema, }; -use minarrow::ffi::arrow_dtype::{ArrowType, CategoricalIndexType}; +use minarrow::ffi::arrow_dtype::ArrowType; #[cfg(feature = "datetime")] use minarrow::enums::time_units::TimeUnit; use minarrow::ffi::schema::Schema; @@ -130,19 +130,7 @@ fn arrow_type_to_pyarrow<'py>( } ArrowType::Dictionary(key_type) => { - let index_ty = match key_type { - #[cfg(feature = "default_categorical_8")] - CategoricalIndexType::UInt8 => pa.call_method0("uint8")?, - #[cfg(feature = "extended_categorical")] - CategoricalIndexType::UInt16 => pa.call_method0("uint16")?, - #[cfg(any( - not(feature = "default_categorical_8"), - feature = "extended_categorical" - ))] - CategoricalIndexType::UInt32 => pa.call_method0("uint32")?, - #[cfg(feature = "extended_categorical")] - CategoricalIndexType::UInt64 => pa.call_method0("uint64")?, - }; + let index_ty = pa.call_method0(key_type.arrow_index_name())?; let value_ty = pa.call_method0("utf8")?; pa.call_method1("dictionary", (index_ty, value_ty)) } diff --git a/src/ffi/arrow_dtype.rs b/src/ffi/arrow_dtype.rs index f2a20ef..b45d22e 100644 --- a/src/ffi/arrow_dtype.rs +++ b/src/ffi/arrow_dtype.rs @@ -404,6 +404,31 @@ pub enum CategoricalIndexType { UInt64, } +impl CategoricalIndexType { + /// The Arrow name of the integer type that carries the dictionary's keys, + /// as used by Arrow and PyArrow. + /// + /// The variants present in a build depend on the categorical width + /// features. A downstream crate reads the name here rather than matching on + /// the enum, because such a match compiles only while both crates select + /// the same widths. + pub fn arrow_index_name(&self) -> &'static str { + match self { + #[cfg(feature = "default_categorical_8")] + CategoricalIndexType::UInt8 => "uint8", + #[cfg(feature = "extended_categorical")] + CategoricalIndexType::UInt16 => "uint16", + #[cfg(any( + not(feature = "default_categorical_8"), + feature = "extended_categorical" + ))] + CategoricalIndexType::UInt32 => "uint32", + #[cfg(feature = "extended_categorical")] + CategoricalIndexType::UInt64 => "uint64", + } + } +} + // Design documentation: arrow_type() // // Whilst `arrow_type()` could be on a trait, the ergonomics of using one aren't great