Skip to content

Commit 0d4f087

Browse files
authored
feat(deps): upgrade pyo3 (#325)
* chore(deps): upgrade pyo3 and arrow Signed-off-by: Luka Peschke <luka.peschke@toucantoco.com> * chore: fix all pyo3 deprecation warnings Signed-off-by: Luka Peschke <luka.peschke@toucantoco.com> --------- Signed-off-by: Luka Peschke <luka.peschke@toucantoco.com>
1 parent c8fea77 commit 0d4f087

File tree

8 files changed

+251
-210
lines changed

8 files changed

+251
-210
lines changed

Cargo.lock

Lines changed: 125 additions & 125 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ crate-type = ["cdylib"]
2525

2626
[dependencies]
2727
# There's a lot of stuff we don't want here, such as serde support
28-
arrow = { version = "53.2.0", default-features = false, features = ["pyarrow"] }
29-
calamine = { version = "0.26.1", features = ["dates"] }
30-
chrono = { version = "0.4.39", default-features = false }
28+
arrow = { version = "^54.0.0", default-features = false, features = [
29+
"pyarrow",
30+
] }
31+
calamine = { version = "^0.26.1", features = ["dates"] }
32+
chrono = { version = "^0.4.39", default-features = false }
3133
log = "0.4.25"
32-
pyo3 = { version = "0.22.6", features = ["abi3-py39"] }
33-
pyo3-log = "0.11.0"
34+
pyo3 = { version = "^0.23.4", features = ["abi3-py39"] }
35+
pyo3-log = "^0.12.1"
3436

3537
[dev-dependencies]
36-
pretty_assertions = "1.4.1"
37-
rstest = { version = "0.24.0", default-features = false }
38+
pretty_assertions = "^1.4.1"
39+
rstest = { version = "^0.24.0", default-features = false }
3840

3941
# NOTE: This is a hack to bypass pyo3 limitations when testing:
4042
# https://pyo3.rs/v0.22.3/faq.html#i-cant-run-cargo-test-or-i-cant-build-in-a-cargo-workspace-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror

src/lib.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,38 +55,32 @@ fn _fastexcel(m: &Bound<'_, PyModule>) -> PyResult<()> {
5555

5656
// errors
5757
[
58-
(
59-
"FastExcelError",
60-
py.get_type_bound::<py_errors::FastExcelError>(),
61-
),
58+
("FastExcelError", py.get_type::<py_errors::FastExcelError>()),
6259
(
6360
"UnsupportedColumnTypeCombinationError",
64-
py.get_type_bound::<py_errors::UnsupportedColumnTypeCombinationError>(),
61+
py.get_type::<py_errors::UnsupportedColumnTypeCombinationError>(),
6562
),
6663
(
6764
"CannotRetrieveCellDataError",
68-
py.get_type_bound::<py_errors::CannotRetrieveCellDataError>(),
65+
py.get_type::<py_errors::CannotRetrieveCellDataError>(),
6966
),
7067
(
7168
"CalamineCellError",
72-
py.get_type_bound::<py_errors::CalamineCellError>(),
73-
),
74-
(
75-
"CalamineError",
76-
py.get_type_bound::<py_errors::CalamineError>(),
69+
py.get_type::<py_errors::CalamineCellError>(),
7770
),
71+
("CalamineError", py.get_type::<py_errors::CalamineError>()),
7872
(
7973
"SheetNotFoundError",
80-
py.get_type_bound::<py_errors::SheetNotFoundError>(),
74+
py.get_type::<py_errors::SheetNotFoundError>(),
8175
),
8276
(
8377
"ColumnNotFoundError",
84-
py.get_type_bound::<py_errors::ColumnNotFoundError>(),
78+
py.get_type::<py_errors::ColumnNotFoundError>(),
8579
),
86-
("ArrowError", py.get_type_bound::<py_errors::ArrowError>()),
80+
("ArrowError", py.get_type::<py_errors::ArrowError>()),
8781
(
8882
"InvalidParametersError",
89-
py.get_type_bound::<py_errors::InvalidParametersError>(),
83+
py.get_type::<py_errors::InvalidParametersError>(),
9084
),
9185
]
9286
.into_iter()

src/types/dtype.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use arrow::datatypes::{DataType as ArrowDataType, TimeUnit};
99
use calamine::{CellErrorType, CellType, DataType, Range};
1010
use log::warn;
1111
use pyo3::{
12-
prelude::PyAnyMethods, Bound, FromPyObject, PyAny, PyObject, PyResult, Python, ToPyObject,
12+
prelude::PyAnyMethods, types::PyString, Bound, FromPyObject, IntoPyObject, IntoPyObjectRef,
13+
PyAny, PyResult, Python,
1314
};
1415

1516
use crate::error::{py_errors::IntoPyResult, FastExcelError, FastExcelErrorKind, FastExcelResult};
@@ -64,9 +65,26 @@ impl Display for DType {
6465
}
6566
}
6667

67-
impl ToPyObject for DType {
68-
fn to_object(&self, py: Python<'_>) -> PyObject {
69-
self.to_string().to_object(py)
68+
impl<'py> IntoPyObject<'py> for DType {
69+
type Target = PyString;
70+
71+
type Output = Bound<'py, Self::Target>;
72+
73+
type Error = std::convert::Infallible;
74+
75+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
76+
self.to_string().into_pyobject(py)
77+
}
78+
}
79+
impl<'py> IntoPyObject<'py> for &DType {
80+
type Target = PyString;
81+
82+
type Output = Bound<'py, Self::Target>;
83+
84+
type Error = std::convert::Infallible;
85+
86+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
87+
self.to_string().into_pyobject(py)
7088
}
7189
}
7290

@@ -86,6 +104,7 @@ impl FromPyObject<'_> for DType {
86104

87105
pub(crate) type DTypeMap = HashMap<IdxOrName, DType>;
88106

107+
#[derive(IntoPyObject, IntoPyObjectRef)]
89108
pub(crate) enum DTypes {
90109
All(DType),
91110
Map(DTypeMap),
@@ -110,15 +129,6 @@ impl FromPyObject<'_> for DTypes {
110129
}
111130
}
112131

113-
impl ToPyObject for DTypes {
114-
fn to_object(&self, py: Python<'_>) -> PyObject {
115-
match self {
116-
DTypes::All(dtype) => dtype.to_object(py),
117-
DTypes::Map(dtype_map) => dtype_map.to_object(py),
118-
}
119-
}
120-
}
121-
122132
impl From<&DType> for ArrowDataType {
123133
fn from(dtype: &DType) -> Self {
124134
match dtype {
@@ -229,7 +239,11 @@ fn get_cell_dtype<DT: CellType + Debug + DataType>(
229239
match cell.get_error() {
230240
// considering cells with #N/A! or #REF! as null
231241
Some(
232-
CellErrorType::NA | CellErrorType::Value | CellErrorType::Null | CellErrorType::Ref | CellErrorType::Num,
242+
CellErrorType::NA
243+
| CellErrorType::Value
244+
| CellErrorType::Null
245+
| CellErrorType::Ref
246+
| CellErrorType::Num,
233247
) => Ok(DType::Null),
234248
Some(err) => Err(FastExcelErrorKind::CalamineCellError(err.to_owned()).into()),
235249
None => Err(FastExcelErrorKind::Internal(format!(

src/types/idx_or_name.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use pyo3::{
2-
prelude::PyAnyMethods, Bound, FromPyObject, PyAny, PyObject, PyResult, Python, ToPyObject,
2+
prelude::PyAnyMethods, Bound, FromPyObject, IntoPyObject, IntoPyObjectExt, PyAny, PyResult,
3+
Python,
34
};
45

56
use crate::error::{py_errors::IntoPyResult, FastExcelError, FastExcelErrorKind, FastExcelResult};
@@ -42,11 +43,32 @@ impl FromPyObject<'_> for IdxOrName {
4243
}
4344
}
4445

45-
impl ToPyObject for IdxOrName {
46-
fn to_object(&self, py: Python<'_>) -> PyObject {
46+
impl<'py> IntoPyObject<'py> for IdxOrName {
47+
type Target = PyAny;
48+
49+
type Output = Bound<'py, Self::Target>;
50+
51+
type Error = pyo3::PyErr;
52+
53+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
54+
match self {
55+
IdxOrName::Idx(idx) => idx.into_bound_py_any(py),
56+
IdxOrName::Name(name) => name.into_bound_py_any(py),
57+
}
58+
}
59+
}
60+
61+
impl<'py> IntoPyObject<'py> for &IdxOrName {
62+
type Target = PyAny;
63+
64+
type Output = Bound<'py, Self::Target>;
65+
66+
type Error = pyo3::PyErr;
67+
68+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
4769
match self {
48-
IdxOrName::Idx(idx) => idx.to_object(py),
49-
IdxOrName::Name(name) => name.to_object(py),
70+
IdxOrName::Idx(idx) => idx.into_bound_py_any(py),
71+
IdxOrName::Name(name) => name.into_bound_py_any(py),
5072
}
5173
}
5274
}

src/types/python/excelreader.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
};
55

66
use arrow::{pyarrow::ToPyArrow, record_batch::RecordBatch};
7-
use pyo3::{prelude::PyObject, pyclass, pymethods, Bound, IntoPy, PyAny, PyResult, Python};
7+
use pyo3::{pyclass, pymethods, Bound, IntoPyObjectExt, PyAny, PyResult, Python};
88

99
use calamine::{
1010
open_workbook_auto, open_workbook_auto_from_rs, Data, DataRef, HeaderRow, Range, Reader,
@@ -172,7 +172,7 @@ impl ExcelReader {
172172
}
173173

174174
#[allow(clippy::too_many_arguments)]
175-
fn build_sheet(
175+
fn build_sheet<'py>(
176176
&mut self,
177177
sheet_meta: CalamineSheet,
178178
header_row: Option<usize>,
@@ -181,11 +181,11 @@ impl ExcelReader {
181181
n_rows: Option<usize>,
182182
schema_sample_rows: Option<usize>,
183183
dtype_coercion: DTypeCoercion,
184-
use_columns: Option<&Bound<'_, PyAny>>,
184+
use_columns: Option<&Bound<'py, PyAny>>,
185185
dtypes: Option<DTypes>,
186186
eager: bool,
187-
py: Python<'_>,
188-
) -> PyResult<PyObject> {
187+
py: Python<'py>,
188+
) -> PyResult<Bound<'py, PyAny>> {
189189
// calamine `header_row` is the first row of the range to be read.
190190
// For us `header_row` can be `None` (meaning there is no header and we should start reading
191191
// the data at the beginning)
@@ -219,6 +219,7 @@ impl ExcelReader {
219219
)
220220
.into_pyresult()
221221
.and_then(|rb| rb.to_pyarrow(py))
222+
.map(|py_object| py_object.into_bound(py))
222223
} else {
223224
let range = self
224225
.sheets
@@ -242,13 +243,13 @@ impl ExcelReader {
242243
if eager {
243244
sheet.to_arrow(py)
244245
} else {
245-
Ok(sheet.into_py(py))
246+
sheet.into_bound_py_any(py)
246247
}
247248
}
248249
}
249250

250251
#[allow(clippy::too_many_arguments)]
251-
fn build_table(
252+
fn build_table<'py>(
252253
&mut self,
253254
name: String,
254255
header_row: Option<usize>,
@@ -260,8 +261,8 @@ impl ExcelReader {
260261
use_columns: Option<&Bound<'_, PyAny>>,
261262
dtypes: Option<DTypes>,
262263
eager: bool,
263-
py: Python<'_>,
264-
) -> PyResult<PyObject> {
264+
py: Python<'py>,
265+
) -> PyResult<Bound<'py, PyAny>> {
265266
let selected_columns = Self::build_selected_columns(use_columns).into_pyresult()?;
266267

267268
let table = self.sheets.get_table(&name).into_pyresult()?;
@@ -287,9 +288,9 @@ impl ExcelReader {
287288
.into_pyresult()?;
288289

289290
if eager {
290-
excel_table.to_arrow(py)
291+
excel_table.to_arrow(py).map(|py_obj| py_obj.into_bound(py))
291292
} else {
292-
Ok(excel_table.into_py(py))
293+
excel_table.into_bound_py_any(py)
293294
}
294295
}
295296
}
@@ -336,20 +337,20 @@ impl ExcelReader {
336337
eager = false,
337338
))]
338339
#[allow(clippy::too_many_arguments)]
339-
pub fn load_sheet(
340+
pub fn load_sheet<'py>(
340341
&mut self,
341-
idx_or_name: &Bound<'_, PyAny>,
342+
idx_or_name: &Bound<'py, PyAny>,
342343
header_row: Option<usize>,
343344
column_names: Option<Vec<String>>,
344345
skip_rows: Option<usize>,
345346
n_rows: Option<usize>,
346347
schema_sample_rows: Option<usize>,
347348
dtype_coercion: DTypeCoercion,
348-
use_columns: Option<&Bound<'_, PyAny>>,
349+
use_columns: Option<&Bound<'py, PyAny>>,
349350
dtypes: Option<DTypes>,
350351
eager: bool,
351-
py: Python<'_>,
352-
) -> PyResult<PyObject> {
352+
py: Python<'py>,
353+
) -> PyResult<Bound<'py, PyAny>> {
353354
// Cannot use NonZeroUsize in the parameters, as it is not supported by pyo3
354355
if let Some(0) = schema_sample_rows {
355356
return Err(FastExcelErrorKind::InvalidParameters(
@@ -414,20 +415,20 @@ impl ExcelReader {
414415
eager = false,
415416
))]
416417
#[allow(clippy::too_many_arguments)]
417-
pub fn load_table(
418+
pub fn load_table<'py>(
418419
&mut self,
419-
name: &Bound<'_, PyString>,
420+
name: &Bound<'py, PyString>,
420421
header_row: Option<usize>,
421422
column_names: Option<Vec<String>>,
422423
skip_rows: usize,
423424
n_rows: Option<usize>,
424425
schema_sample_rows: Option<usize>,
425426
dtype_coercion: DTypeCoercion,
426-
use_columns: Option<&Bound<'_, PyAny>>,
427+
use_columns: Option<&Bound<'py, PyAny>>,
427428
dtypes: Option<DTypes>,
428429
eager: bool,
429-
py: Python<'_>,
430-
) -> PyResult<PyObject> {
430+
py: Python<'py>,
431+
) -> PyResult<Bound<'py, PyAny>> {
431432
// Cannot use NonZeroUsize in the parameters, as it is not supported by pyo3
432433
if let Some(0) = schema_sample_rows {
433434
return Err(FastExcelErrorKind::InvalidParameters(

0 commit comments

Comments
 (0)