Skip to content

Commit 5c96bec

Browse files
authored
minimal upgrade to PyO3 0.23 (ignoring deprecations) (#1556)
1 parent 334e3df commit 5c96bec

File tree

16 files changed

+107
-78
lines changed

16 files changed

+107
-78
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ rust-version = "1.75"
2929
[dependencies]
3030
# TODO it would be very nice to remove the "py-clone" feature as it can panic,
3131
# but needs a bit of work to make sure it's not used in the codebase
32-
pyo3 = { version = "0.22.6", features = ["generate-import-lib", "num-bigint", "py-clone"] }
32+
pyo3 = { version = "0.23.2", features = ["generate-import-lib", "num-bigint", "py-clone"] }
3333
regex = "1.11.1"
3434
strum = { version = "0.26.3", features = ["derive"] }
3535
strum_macros = "0.26.4"
@@ -46,7 +46,7 @@ base64 = "0.22.1"
4646
num-bigint = "0.4.6"
4747
python3-dll-a = "0.2.10"
4848
uuid = "1.11.0"
49-
jiter = { version = "0.7.1", features = ["python"] }
49+
jiter = { version = "0.8.0", features = ["python"] }
5050
hex = "0.4.3"
5151

5252
[lib]
@@ -74,12 +74,12 @@ debug = true
7474
strip = false
7575

7676
[dev-dependencies]
77-
pyo3 = { version = "0.22.6", features = ["auto-initialize"] }
77+
pyo3 = { version = "0.23.2", features = ["auto-initialize"] }
7878

7979
[build-dependencies]
8080
version_check = "0.9.5"
8181
# used where logic has to be version/distribution specific, e.g. pypy
82-
pyo3-build-config = { version = "0.22.6" }
82+
pyo3-build-config = { version = "0.23.2" }
8383

8484
[lints.clippy]
8585
dbg_macro = "warn"

benches/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(test)]
2+
#![allow(deprecated)] // FIXME: just used during upgrading PyO3 to 0.23
23

34
extern crate test;
45

src/errors/validation_exception.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ impl ValidationError {
386386
let args = (
387387
borrow.title.bind(py),
388388
borrow.errors(py, include_url_env(py), true, true)?,
389-
borrow.input_type.into_py(py),
389+
borrow.input_type.into_pyobject(py)?,
390390
borrow.hide_input,
391391
)
392392
.into_py(slf.py());

src/input/datetime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ impl TzInfo {
527527
}
528528

529529
#[allow(unused_variables)]
530-
fn dst(&self, dt: &Bound<'_, PyAny>) -> Option<&PyDelta> {
530+
fn dst(&self, dt: &Bound<'_, PyAny>) -> Option<Bound<'_, PyDelta>> {
531531
None
532532
}
533533

src/input/input_abstract.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use std::convert::Infallible;
12
use std::fmt;
23

34
use pyo3::exceptions::PyValueError;
4-
use pyo3::types::{PyDict, PyList};
5+
use pyo3::types::{PyDict, PyList, PyString};
56
use pyo3::{intern, prelude::*};
67

78
use crate::errors::{ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult};
@@ -20,13 +21,17 @@ pub enum InputType {
2021
String,
2122
}
2223

23-
impl IntoPy<PyObject> for InputType {
24-
fn into_py(self, py: Python<'_>) -> PyObject {
25-
match self {
26-
Self::Json => intern!(py, "json").into_py(py),
27-
Self::Python => intern!(py, "python").into_py(py),
28-
Self::String => intern!(py, "string").into_py(py),
29-
}
24+
impl<'py> IntoPyObject<'py> for InputType {
25+
type Target = PyString;
26+
type Output = Bound<'py, PyString>;
27+
type Error = Infallible;
28+
29+
fn into_pyobject(self, py: Python<'_>) -> Result<Bound<'_, PyString>, Infallible> {
30+
Ok(match self {
31+
Self::Json => intern!(py, "json").clone(),
32+
Self::Python => intern!(py, "python").clone(),
33+
Self::String => intern!(py, "string").clone(),
34+
})
3035
}
3136
}
3237

src/input/return_enums.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,18 +278,16 @@ pub(crate) fn iterate_mapping_items<'a, 'py>(
278278
.items()
279279
.map_err(|e| mapping_err(e, py, input))?
280280
.iter()
281-
.map_err(|e| mapping_err(e, py, input))?
282-
.map(move |item| match item {
283-
Ok(item) => item.extract().map_err(|_| {
281+
.map(move |item| {
282+
item.extract().map_err(|_| {
284283
ValError::new(
285284
ErrorType::MappingType {
286285
error: MAPPING_TUPLE_ERROR.into(),
287286
context: None,
288287
},
289288
input,
290289
)
291-
}),
292-
Err(e) => Err(mapping_err(e, py, input)),
290+
})
293291
});
294292
Ok(iterator)
295293
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(has_coverage_attribute, feature(coverage_attribute))]
2+
#![allow(deprecated)] // FIXME: just used during upgrading PyO3 to 0.23
23

34
extern crate core;
45

src/lookup_key.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::fmt;
44
use pyo3::exceptions::{PyAttributeError, PyTypeError};
55
use pyo3::prelude::*;
66
use pyo3::types::{PyDict, PyList, PyMapping, PyString};
7+
use pyo3::IntoPyObjectExt;
78

89
use jiter::{JsonObject, JsonValue};
910

@@ -407,14 +408,18 @@ impl fmt::Display for PathItem {
407408
}
408409
}
409410

410-
impl ToPyObject for PathItem {
411-
fn to_object(&self, py: Python<'_>) -> PyObject {
411+
impl<'py> IntoPyObject<'py> for &'_ PathItem {
412+
type Target = PyAny;
413+
type Output = Bound<'py, PyAny>;
414+
type Error = PyErr;
415+
416+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
412417
match self {
413-
Self::S(_, val) => val.to_object(py),
414-
Self::Pos(val) => val.to_object(py),
415-
Self::Neg(val) => {
418+
PathItem::S(_, val) => Ok(val.bind(py).clone().into_any()),
419+
PathItem::Pos(val) => val.into_bound_py_any(py),
420+
PathItem::Neg(val) => {
416421
let neg_value = -(*val as i64);
417-
neg_value.to_object(py)
422+
neg_value.into_bound_py_any(py)
418423
}
419424
}
420425
}

src/serializers/extra.rs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use std::cell::RefCell;
21
use std::fmt;
2+
use std::sync::Mutex;
33

44
use pyo3::exceptions::{PyTypeError, PyValueError};
55
use pyo3::intern;
@@ -370,18 +370,27 @@ impl From<bool> for WarningsMode {
370370
}
371371
}
372372

373-
#[derive(Clone)]
374373
#[cfg_attr(debug_assertions, derive(Debug))]
375374
pub(crate) struct CollectWarnings {
376375
mode: WarningsMode,
377-
warnings: RefCell<Option<Vec<String>>>,
376+
// FIXME: mutex is to satisfy PyO3 0.23, we should be able to refactor this away
377+
warnings: Mutex<Vec<String>>,
378+
}
379+
380+
impl Clone for CollectWarnings {
381+
fn clone(&self) -> Self {
382+
Self {
383+
mode: self.mode,
384+
warnings: Mutex::new(self.warnings.lock().expect("lock poisoned").clone()),
385+
}
386+
}
378387
}
379388

380389
impl CollectWarnings {
381390
pub(crate) fn new(mode: WarningsMode) -> Self {
382391
Self {
383392
mode,
384-
warnings: RefCell::new(None),
393+
warnings: Mutex::new(Vec::new()),
385394
}
386395
}
387396

@@ -447,41 +456,46 @@ impl CollectWarnings {
447456
}
448457

449458
fn add_warning(&self, message: String) {
450-
let mut op_warnings = self.warnings.borrow_mut();
451-
if let Some(ref mut warnings) = *op_warnings {
452-
warnings.push(message);
453-
} else {
454-
*op_warnings = Some(vec![message]);
455-
}
459+
self.warnings.lock().expect("lock poisoned").push(message);
456460
}
457461

458462
pub fn final_check(&self, py: Python) -> PyResult<()> {
459463
if self.mode == WarningsMode::None {
460464
return Ok(());
461465
}
462-
match *self.warnings.borrow() {
463-
Some(ref warnings) => {
464-
let message = format!("Pydantic serializer warnings:\n {}", warnings.join("\n "));
465-
if self.mode == WarningsMode::Warn {
466-
let user_warning_type = py.import_bound("builtins")?.getattr("UserWarning")?;
467-
PyErr::warn_bound(py, &user_warning_type, &message, 0)
468-
} else {
469-
Err(PydanticSerializationError::new_err(message))
470-
}
471-
}
472-
_ => Ok(()),
466+
let warnings = self.warnings.lock().expect("lock poisoned");
467+
468+
if warnings.is_empty() {
469+
return Ok(());
470+
}
471+
472+
let message = format!("Pydantic serializer warnings:\n {}", warnings.join("\n "));
473+
if self.mode == WarningsMode::Warn {
474+
let user_warning_type = py.import_bound("builtins")?.getattr("UserWarning")?;
475+
PyErr::warn_bound(py, &user_warning_type, &message, 0)
476+
} else {
477+
Err(PydanticSerializationError::new_err(message))
473478
}
474479
}
475480
}
476481

477-
#[derive(Default, Clone)]
482+
#[derive(Default)]
478483
#[cfg_attr(debug_assertions, derive(Debug))]
479484
pub struct SerRecursionState {
480-
guard: RefCell<RecursionState>,
485+
// FIXME: mutex is to satisfy PyO3 0.23, we should be able to refactor this away
486+
guard: Mutex<RecursionState>,
487+
}
488+
489+
impl Clone for SerRecursionState {
490+
fn clone(&self) -> Self {
491+
Self {
492+
guard: Mutex::new(self.guard.lock().expect("lock poisoned").clone()),
493+
}
494+
}
481495
}
482496

483497
impl ContainsRecursionState for &'_ Extra<'_> {
484498
fn access_recursion_state<R>(&mut self, f: impl FnOnce(&mut RecursionState) -> R) -> R {
485-
f(&mut self.rec_guard.guard.borrow_mut())
499+
f(&mut self.rec_guard.guard.lock().expect("lock poisoned"))
486500
}
487501
}

0 commit comments

Comments
 (0)