Skip to content

Commit f6a87d9

Browse files
committed
build against PyO3 0.27 draft
1 parent 396499c commit f6a87d9

File tree

10 files changed

+49
-47
lines changed

10 files changed

+49
-47
lines changed

Cargo.lock

Lines changed: 6 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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,8 @@ too_many_lines = "allow"
105105
unnecessary_wraps = "allow"
106106
unused_self = "allow"
107107
used_underscore_binding = "allow"
108+
109+
[patch.crates-io]
110+
pyo3 = { git = "https://github.com/pyo3/pyo3.git" }
111+
pyo3-build-config = { git = "https://github.com/pyo3/pyo3.git" }
112+
jiter = { git = "https://github.com/pydantic/jiter.git", branch = "dh/pyo3-0.27" }

src/build_tools.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::sync::OnceLock;
77
use pyo3::exceptions::PyException;
88
use pyo3::prelude::*;
99
use pyo3::types::{PyDict, PyList, PyString};
10-
use pyo3::{intern, FromPyObject, PyErrArguments};
10+
use pyo3::{intern, PyErrArguments};
1111

1212
use crate::errors::{PyLineError, ValError};
1313
use crate::input::InputType;
@@ -21,7 +21,7 @@ pub fn schema_or_config<'py, T>(
2121
config_key: &Bound<'py, PyString>,
2222
) -> PyResult<Option<T>>
2323
where
24-
T: FromPyObject<'py>,
24+
T: FromPyObjectOwned<'py>,
2525
{
2626
match schema.get_as(schema_key)? {
2727
Some(v) => Ok(Some(v)),
@@ -38,7 +38,7 @@ pub fn schema_or_config_same<'py, T>(
3838
key: &Bound<'py, PyString>,
3939
) -> PyResult<Option<T>>
4040
where
41-
T: FromPyObject<'py>,
41+
T: FromPyObjectOwned<'py>,
4242
{
4343
schema_or_config(schema, config, key, key)
4444
}

src/errors/types.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub fn list_all_errors(py: Python<'_>) -> PyResult<Bound<'_, PyList>> {
4242
PyList::new(py, errors)
4343
}
4444

45-
fn field_from_context<'py, T: FromPyObject<'py>>(
45+
fn field_from_context<'py, T: FromPyObjectOwned<'py>>(
4646
context: Option<&Bound<'py, PyDict>>,
4747
field_name: &str,
4848
enum_name: &str,
@@ -56,7 +56,7 @@ fn field_from_context<'py, T: FromPyObject<'py>>(
5656
.map_err(|_| py_error_type!(PyTypeError; "{}: '{}' context value must be a {}", enum_name, field_name, type_name_fn()))
5757
}
5858

59-
fn cow_field_from_context<'py, T: FromPyObject<'py>, B: ToOwned<Owned = T> + ?Sized + 'static>(
59+
fn cow_field_from_context<'py, T: FromPyObjectOwned<'py>, B: ToOwned<Owned = T> + ?Sized + 'static>(
6060
context: Option<&Bound<'py, PyDict>>,
6161
field_name: &str,
6262
enum_name: &str,
@@ -809,9 +809,11 @@ impl From<Int> for Number {
809809
}
810810
}
811811

812-
impl FromPyObject<'_> for Number {
813-
fn extract_bound(obj: &Bound<'_, PyAny>) -> PyResult<Self> {
814-
if let Some(int) = extract_i64(obj) {
812+
impl FromPyObject<'_, '_> for Number {
813+
type Error = PyErr;
814+
815+
fn extract(obj: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
816+
if let Some(int) = extract_i64(&obj) {
815817
Ok(Number::Int(int))
816818
} else if let Ok(float) = obj.extract::<f64>() {
817819
Ok(Number::Float(float))

src/input/return_enums.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -706,9 +706,11 @@ impl Rem for &Int {
706706
}
707707
}
708708

709-
impl FromPyObject<'_> for Int {
710-
fn extract_bound(obj: &Bound<'_, PyAny>) -> PyResult<Self> {
711-
match extract_int(obj) {
709+
impl FromPyObject<'_, '_> for Int {
710+
type Error = PyErr;
711+
712+
fn extract(obj: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
713+
match extract_int(&obj) {
712714
Some(i) => Ok(i),
713715
None => py_err!(PyTypeError; "Expected int, got {}", obj.get_type()),
714716
}

src/serializers/config.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,9 @@ pub fn utf8_py_error(py: Python, err: Utf8Error, data: &[u8]) -> PyErr {
347347
}
348348
}
349349

350-
impl FromPyObject<'_> for InfNanMode {
351-
fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Self> {
350+
impl FromPyObject<'_, '_> for InfNanMode {
351+
type Error = PyErr;
352+
fn extract(ob: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
352353
Self::from_str(ob.downcast::<PyString>()?.to_str()?)
353354
}
354355
}

src/serializers/extra.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,10 @@ pub enum WarningsMode {
317317
Error,
318318
}
319319

320-
impl<'py> FromPyObject<'py> for WarningsMode {
321-
fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<WarningsMode> {
320+
impl<'py> FromPyObject<'_, 'py> for WarningsMode {
321+
type Error = PyErr;
322+
323+
fn extract(ob: Borrowed<'_, 'py, PyAny>) -> PyResult<WarningsMode> {
322324
if let Ok(bool_mode) = ob.downcast::<PyBool>() {
323325
Ok(bool_mode.is_true().into())
324326
} else if let Ok(str_mode) = ob.extract::<&str>() {

src/tools.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,40 @@ use core::fmt;
33
use num_bigint::BigInt;
44

55
use pyo3::exceptions::PyKeyError;
6+
use pyo3::intern;
67
use pyo3::prelude::*;
78
use pyo3::types::{PyDict, PyString};
8-
use pyo3::{intern, FromPyObject};
99

1010
use crate::input::Int;
1111
use jiter::{cached_py_string, StringCacheMode};
1212

1313
pub trait SchemaDict<'py> {
1414
fn get_as<T>(&self, key: &Bound<'py, PyString>) -> PyResult<Option<T>>
1515
where
16-
T: FromPyObject<'py>;
16+
T: FromPyObjectOwned<'py>;
1717

1818
fn get_as_req<T>(&self, key: &Bound<'py, PyString>) -> PyResult<T>
1919
where
20-
T: FromPyObject<'py>;
20+
T: FromPyObjectOwned<'py>;
2121
}
2222

2323
impl<'py> SchemaDict<'py> for Bound<'py, PyDict> {
2424
fn get_as<T>(&self, key: &Bound<'py, PyString>) -> PyResult<Option<T>>
2525
where
26-
T: FromPyObject<'py>,
26+
T: FromPyObjectOwned<'py>,
2727
{
2828
match self.get_item(key)? {
29-
Some(t) => t.extract().map(Some),
29+
Some(t) => t.extract().map_err(Into::into).map(Some),
3030
None => Ok(None),
3131
}
3232
}
3333

3434
fn get_as_req<T>(&self, key: &Bound<'py, PyString>) -> PyResult<T>
3535
where
36-
T: FromPyObject<'py>,
36+
T: FromPyObjectOwned<'py>,
3737
{
3838
match self.get_item(key)? {
39-
Some(t) => t.extract(),
39+
Some(t) => t.extract().map_err(Into::into),
4040
None => py_err!(PyKeyError; "{}", key),
4141
}
4242
}
@@ -45,7 +45,7 @@ impl<'py> SchemaDict<'py> for Bound<'py, PyDict> {
4545
impl<'py> SchemaDict<'py> for Option<&Bound<'py, PyDict>> {
4646
fn get_as<T>(&self, key: &Bound<'py, PyString>) -> PyResult<Option<T>>
4747
where
48-
T: FromPyObject<'py>,
48+
T: FromPyObjectOwned<'py>,
4949
{
5050
match self {
5151
Some(d) => d.get_as(key),
@@ -56,7 +56,7 @@ impl<'py> SchemaDict<'py> for Option<&Bound<'py, PyDict>> {
5656
#[cfg_attr(has_coverage_attribute, coverage(off))]
5757
fn get_as_req<T>(&self, key: &Bound<'py, PyString>) -> PyResult<T>
5858
where
59-
T: FromPyObject<'py>,
59+
T: FromPyObjectOwned<'py>,
6060
{
6161
match self {
6262
Some(d) => d.get_as_req(key),

src/url.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl PyUrl {
103103
};
104104
ValidationError::from_val_error(py, name, InputType::Python, e, None, false, false)
105105
})?
106-
.downcast_bound::<Self>(py)?
106+
.cast_bound::<Self>(py)?
107107
.get()
108108
.clone(); // FIXME: avoid the clone, would need to make `validate` be aware of what URL subclass to create
109109
Ok(url_obj)
@@ -308,7 +308,7 @@ impl PyMultiHostUrl {
308308
};
309309
ValidationError::from_val_error(py, name, InputType::Python, e, None, false, false)
310310
})?
311-
.downcast_bound::<Self>(py)?
311+
.cast_bound::<Self>(py)?
312312
.get()
313313
.clone(); // FIXME: avoid the clone, would need to make `validate` be aware of what URL subclass to create
314314
Ok(url_obj)
@@ -521,8 +521,10 @@ impl UrlHostParts {
521521
}
522522
}
523523

524-
impl FromPyObject<'_> for UrlHostParts {
525-
fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Self> {
524+
impl FromPyObject<'_, '_> for UrlHostParts {
525+
type Error = PyErr;
526+
527+
fn extract(ob: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
526528
let py = ob.py();
527529
let dict = ob.downcast::<PyDict>()?;
528530
Ok(UrlHostParts {

src/validators/uuid.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,8 @@ const UUID_IS_SAFE: &str = "is_safe";
2727

2828
static UUID_TYPE: PyOnceLock<Py<PyType>> = PyOnceLock::new();
2929

30-
fn import_type(py: Python, module: &str, attr: &str) -> PyResult<Py<PyType>> {
31-
py.import(module)?.getattr(attr)?.extract()
32-
}
33-
3430
fn get_uuid_type(py: Python<'_>) -> PyResult<&Bound<'_, PyType>> {
35-
Ok(UUID_TYPE
36-
.get_or_init(py, || import_type(py, "uuid", "UUID").unwrap())
37-
.bind(py))
31+
UUID_TYPE.import(py, "uuid", "UUID")
3832
}
3933

4034
#[derive(Debug, Clone, Copy)]

0 commit comments

Comments
 (0)