Replace explicit `try_from` usage by `downcast`

This commit is contained in:
Georg Brandl 2022-11-17 10:35:48 +01:00
parent 7d4dfc32b3
commit d6ac4d51b7
18 changed files with 108 additions and 115 deletions

View File

@ -51,7 +51,7 @@ use crate::types::{
PyTzInfo, PyTzInfoAccess, PyUnicode,
};
use crate::{
AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, PyTryFrom, Python, ToPyObject,
AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject,
};
use chrono::offset::{FixedOffset, Utc};
use chrono::{
@ -97,7 +97,7 @@ impl IntoPy<PyObject> for Duration {
impl FromPyObject<'_> for Duration {
fn extract(ob: &PyAny) -> PyResult<Duration> {
let delta = <PyDelta as PyTryFrom>::try_from(ob)?;
let delta: &PyDelta = ob.downcast()?;
// Python size are much lower than rust size so we do not need bound checks.
// 0 <= microseconds < 1000000
// 0 <= seconds < 3600*24
@ -125,7 +125,7 @@ impl IntoPy<PyObject> for NaiveDate {
impl FromPyObject<'_> for NaiveDate {
fn extract(ob: &PyAny) -> PyResult<NaiveDate> {
let date = <PyDate as PyTryFrom>::try_from(ob)?;
let date: &PyDate = ob.downcast()?;
NaiveDate::from_ymd_opt(
date.get_year(),
date.get_month() as u32,
@ -159,7 +159,7 @@ impl IntoPy<PyObject> for NaiveTime {
impl FromPyObject<'_> for NaiveTime {
fn extract(ob: &PyAny) -> PyResult<NaiveTime> {
let time = <PyTime as PyTryFrom>::try_from(ob)?;
let time: &PyTime = ob.downcast()?;
let ms = time.get_fold() as u32 * 1_000_000 + time.get_microsecond();
let h = time.get_hour() as u32;
let m = time.get_minute() as u32;
@ -198,7 +198,7 @@ impl IntoPy<PyObject> for NaiveDateTime {
impl FromPyObject<'_> for NaiveDateTime {
fn extract(ob: &PyAny) -> PyResult<NaiveDateTime> {
let dt = <PyDateTime as PyTryFrom>::try_from(ob)?;
let dt: &PyDateTime = ob.downcast()?;
// If the user tries to convert a timezone aware datetime into a naive one,
// we return a hard error. We could silently remove tzinfo, or assume local timezone
// and do a conversion, but better leave this decision to the user of the library.
@ -252,7 +252,7 @@ impl<Tz: TimeZone> IntoPy<PyObject> for DateTime<Tz> {
impl FromPyObject<'_> for DateTime<FixedOffset> {
fn extract(ob: &PyAny) -> PyResult<DateTime<FixedOffset>> {
let dt = <PyDateTime as PyTryFrom>::try_from(ob)?;
let dt: &PyDateTime = ob.downcast()?;
let ms = dt.get_fold() as u32 * 1_000_000 + dt.get_microsecond();
let h = dt.get_hour().into();
let m = dt.get_minute().into();
@ -274,7 +274,7 @@ impl FromPyObject<'_> for DateTime<FixedOffset> {
impl FromPyObject<'_> for DateTime<Utc> {
fn extract(ob: &PyAny) -> PyResult<DateTime<Utc>> {
let dt = <PyDateTime as PyTryFrom>::try_from(ob)?;
let dt: &PyDateTime = ob.downcast()?;
let ms = dt.get_fold() as u32 * 1_000_000 + dt.get_microsecond();
let h = dt.get_hour().into();
let m = dt.get_minute().into();
@ -325,14 +325,14 @@ impl FromPyObject<'_> for FixedOffset {
/// Note that the conversion will result in precision lost in microseconds as chrono offset
/// does not supports microseconds.
fn extract(ob: &PyAny) -> PyResult<FixedOffset> {
let py_tzinfo = <PyTzInfo as PyTryFrom>::try_from(ob)?;
let py_tzinfo: &PyTzInfo = ob.downcast()?;
// Passing `ob.py().None()` (so Python's None) to the `utcoffset` function will only
// work for timezones defined as fixed offsets in Python.
// Any other timezone would require a datetime as the parameter, and return
// None if the datetime is not provided.
// Trying to convert None to a PyDelta in the next line will then fail.
let py_timedelta = py_tzinfo.call_method1("utcoffset", (ob.py().None(),))?;
let py_timedelta = <PyDelta as PyTryFrom>::try_from(py_timedelta).map_err(|_| {
let py_timedelta: &PyDelta = py_timedelta.downcast().map_err(|_| {
PyTypeError::new_err(format!(
"{:?} is not a fixed offset timezone",
py_tzinfo
@ -366,7 +366,7 @@ impl IntoPy<PyObject> for Utc {
impl FromPyObject<'_> for Utc {
fn extract(ob: &PyAny) -> PyResult<Utc> {
let py_tzinfo = <PyTzInfo as PyTryFrom>::try_from(ob)?;
let py_tzinfo: &PyTzInfo = ob.downcast()?;
let py_utc = timezone_utc(ob.py());
if py_tzinfo.eq(py_utc)? {
Ok(Utc)

View File

@ -23,7 +23,7 @@
//! The required hashbrown version may vary based on the version of PyO3.
use crate::{
types::{IntoPyDict, PyDict, PySet},
FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, PyTryFrom, Python, ToPyObject,
FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
};
use std::{cmp, hash};
@ -59,7 +59,7 @@ where
S: hash::BuildHasher + Default,
{
fn extract(ob: &'source PyAny) -> Result<Self, PyErr> {
let dict = <PyDict as PyTryFrom>::try_from(ob)?;
let dict: &PyDict = ob.downcast()?;
let mut ret = hashbrown::HashMap::with_capacity_and_hasher(dict.len(), S::default());
for (k, v) in dict.iter() {
ret.insert(K::extract(k)?, V::extract(v)?);
@ -121,7 +121,7 @@ mod tests {
map.insert(1, 1);
let m = map.to_object(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
@ -135,7 +135,7 @@ mod tests {
map.insert(1, 1);
let m: PyObject = map.into_py(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);

View File

@ -93,7 +93,7 @@
//! ```
use crate::types::*;
use crate::{FromPyObject, IntoPy, PyErr, PyObject, PyTryFrom, Python, ToPyObject};
use crate::{FromPyObject, IntoPy, PyErr, PyObject, Python, ToPyObject};
use std::{cmp, hash};
impl<K, V, H> ToPyObject for indexmap::IndexMap<K, V, H>
@ -128,7 +128,7 @@ where
S: hash::BuildHasher + Default,
{
fn extract(ob: &'source PyAny) -> Result<Self, PyErr> {
let dict = <PyDict as PyTryFrom>::try_from(ob)?;
let dict: &PyDict = ob.downcast()?;
let mut ret = indexmap::IndexMap::with_capacity_and_hasher(dict.len(), S::default());
for (k, v) in dict.iter() {
ret.insert(K::extract(k)?, V::extract(v)?);
@ -141,7 +141,7 @@ where
mod test_indexmap {
use crate::types::*;
use crate::{IntoPy, PyObject, PyTryFrom, Python, ToPyObject};
use crate::{IntoPy, PyObject, Python, ToPyObject};
#[test]
fn test_indexmap_indexmap_to_python() {
@ -150,7 +150,7 @@ mod test_indexmap {
map.insert(1, 1);
let m = map.to_object(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
@ -168,7 +168,7 @@ mod test_indexmap {
map.insert(1, 1);
let m: PyObject = map.into_py(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);

View File

@ -3,7 +3,7 @@ use std::{cmp, collections, hash};
use crate::{
inspect::types::TypeInfo,
types::{IntoPyDict, PyDict},
FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyTryFrom, Python, ToPyObject,
FromPyObject, IntoPy, PyAny, PyErr, PyObject, Python, ToPyObject,
};
impl<K, V, H> ToPyObject for collections::HashMap<K, V, H>
@ -69,7 +69,7 @@ where
S: hash::BuildHasher + Default,
{
fn extract(ob: &'source PyAny) -> Result<Self, PyErr> {
let dict = <PyDict as PyTryFrom>::try_from(ob)?;
let dict: &PyDict = ob.downcast()?;
let mut ret = collections::HashMap::with_capacity_and_hasher(dict.len(), S::default());
for (k, v) in dict.iter() {
ret.insert(K::extract(k)?, V::extract(v)?);
@ -88,7 +88,7 @@ where
V: FromPyObject<'source>,
{
fn extract(ob: &'source PyAny) -> Result<Self, PyErr> {
let dict = <PyDict as PyTryFrom>::try_from(ob)?;
let dict: &PyDict = ob.downcast()?;
let mut ret = collections::BTreeMap::new();
for (k, v) in dict.iter() {
ret.insert(K::extract(k)?, V::extract(v)?);
@ -104,7 +104,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::{IntoPy, PyObject, PyTryFrom, Python, ToPyObject};
use crate::{IntoPy, PyObject, Python, ToPyObject};
use std::collections::{BTreeMap, HashMap};
#[test]
@ -114,7 +114,7 @@ mod tests {
map.insert(1, 1);
let m = map.to_object(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
@ -129,7 +129,7 @@ mod tests {
map.insert(1, 1);
let m = map.to_object(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
@ -144,7 +144,7 @@ mod tests {
map.insert(1, 1);
let m: PyObject = map.into_py(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
@ -158,7 +158,7 @@ mod tests {
map.insert(1, 1);
let m: PyObject = map.into_py(py);
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
let py_map: &PyDict = m.downcast(py).unwrap();
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);

View File

@ -2,8 +2,7 @@ use crate::types::PyString;
#[cfg(windows)]
use crate::PyErr;
use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, PyTryFrom, Python,
ToPyObject,
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject,
};
use std::borrow::Cow;
use std::ffi::{OsStr, OsString};
@ -57,7 +56,7 @@ impl ToPyObject for OsStr {
impl FromPyObject<'_> for OsString {
fn extract(ob: &PyAny) -> PyResult<Self> {
let pystring = <PyString as PyTryFrom>::try_from(ob)?; // Cast PyAny to PyString
let pystring: &PyString = ob.downcast()?;
#[cfg(not(windows))]
{

View File

@ -1,6 +1,6 @@
use crate::{
inspect::types::TypeInfo, types::PyBytes, FromPyObject, IntoPy, PyAny, PyObject, PyResult,
PyTryFrom, Python, ToPyObject,
Python, ToPyObject,
};
impl<'a> IntoPy<PyObject> for &'a [u8] {
@ -15,7 +15,7 @@ impl<'a> IntoPy<PyObject> for &'a [u8] {
impl<'a> FromPyObject<'a> for &'a [u8] {
fn extract(obj: &'a PyAny) -> PyResult<Self> {
Ok(<PyBytes as PyTryFrom>::try_from(obj)?.as_bytes())
Ok(obj.downcast::<PyBytes>()?.as_bytes())
}
fn type_input() -> TypeInfo {

View File

@ -2,7 +2,7 @@ use std::borrow::Cow;
use crate::{
inspect::types::TypeInfo, types::PyString, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult,
PyTryFrom, Python, ToPyObject,
Python, ToPyObject,
};
/// Converts a Rust `str` to a Python object.
@ -107,7 +107,7 @@ impl<'a> IntoPy<PyObject> for &'a String {
/// Accepts Python `str` and `unicode` objects.
impl<'source> FromPyObject<'source> for &'source str {
fn extract(ob: &'source PyAny) -> PyResult<Self> {
<PyString as PyTryFrom>::try_from(ob)?.to_str()
ob.downcast::<PyString>()?.to_str()
}
fn type_input() -> TypeInfo {
@ -119,9 +119,7 @@ impl<'source> FromPyObject<'source> for &'source str {
/// Accepts Python `str` and `unicode` objects.
impl FromPyObject<'_> for String {
fn extract(obj: &PyAny) -> PyResult<Self> {
<PyString as PyTryFrom>::try_from(obj)?
.to_str()
.map(ToOwned::to_owned)
obj.downcast::<PyString>()?.to_str().map(ToOwned::to_owned)
}
fn type_input() -> TypeInfo {
@ -131,7 +129,7 @@ impl FromPyObject<'_> for String {
impl FromPyObject<'_> for char {
fn extract(obj: &PyAny) -> PyResult<Self> {
let s = <PyString as PyTryFrom<'_>>::try_from(obj)?.to_str()?;
let s = obj.downcast::<PyString>()?.to_str()?;
let mut iter = s.chars();
if let (Some(ch), None) = (iter.next(), iter.next()) {
Ok(ch)

View File

@ -113,7 +113,7 @@ pub unsafe trait PyNativeType: Sized {
/// # let m = pyo3::types::PyModule::new(py, "test")?;
/// # m.add_class::<Foo>()?;
/// #
/// # let foo: &PyCell<Foo> = pyo3::PyTryFrom::try_from(m.getattr("Foo")?.call0()?)?;
/// # let foo: &PyCell<Foo> = m.getattr("Foo")?.call0()?.downcast()?;
/// # let dict = &foo.borrow().inner;
/// # let dict: &PyDict = dict.as_ref(py);
/// #
@ -150,7 +150,7 @@ pub unsafe trait PyNativeType: Sized {
/// # let m = pyo3::types::PyModule::new(py, "test")?;
/// # m.add_class::<Foo>()?;
/// #
/// # let foo: &PyCell<Foo> = pyo3::PyTryFrom::try_from(m.getattr("Foo")?.call0()?)?;
/// # let foo: &PyCell<Foo> = m.getattr("Foo")?.call0()?.downcast()?;
/// # let bar = &foo.borrow().inner;
/// # let bar: &Bar = &*bar.borrow(py);
/// #

View File

@ -1,8 +1,7 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
use crate::inspect::types::TypeInfo;
use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, PyTryFrom, Python,
ToPyObject,
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject,
};
/// Represents a Python `bool`.
@ -58,7 +57,7 @@ impl IntoPy<PyObject> for bool {
/// Fails with `TypeError` if the input is not a Python `bool`.
impl<'source> FromPyObject<'source> for bool {
fn extract(obj: &'source PyAny) -> PyResult<Self> {
Ok(<PyBool as PyTryFrom>::try_from(obj)?.is_true())
Ok(obj.downcast::<PyBool>()?.is_true())
}
fn type_input() -> TypeInfo {

View File

@ -422,7 +422,7 @@ mod tests {
use crate::exceptions;
#[cfg(not(PyPy))]
use crate::{types::PyList, PyTypeInfo};
use crate::{types::PyTuple, PyTryFrom, Python, ToPyObject};
use crate::{types::PyTuple, Python, ToPyObject};
use std::collections::{BTreeMap, HashMap};
#[test]
@ -478,11 +478,11 @@ mod tests {
Python::with_gil(|py| {
let mut v = HashMap::new();
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert_eq!(0, dict.len());
v.insert(7, 32);
let ob = v.to_object(py);
let dict2 = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict2: &PyDict = ob.downcast(py).unwrap();
assert_eq!(1, dict2.len());
});
}
@ -493,7 +493,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert!(dict.contains(7i32).unwrap());
assert!(!dict.contains(8i32).unwrap());
});
@ -505,7 +505,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert_eq!(32, dict.get_item(7i32).unwrap().extract::<i32>().unwrap());
assert!(dict.get_item(8i32).is_none());
});
@ -518,7 +518,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert_eq!(
32,
dict.get_item_with_error(7i32)
@ -541,7 +541,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert!(dict.set_item(7i32, 42i32).is_ok()); // change
assert!(dict.set_item(8i32, 123i32).is_ok()); // insert
assert_eq!(
@ -577,7 +577,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert!(dict.set_item(7i32, 42i32).is_ok()); // change
assert!(dict.set_item(8i32, 123i32).is_ok()); // insert
assert_eq!(32i32, v[&7i32]); // not updated!
@ -591,7 +591,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert!(dict.del_item(7i32).is_ok());
assert_eq!(0, dict.len());
assert!(dict.get_item(7i32).is_none());
@ -604,7 +604,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
assert!(dict.del_item(7i32).is_ok()); // change
assert_eq!(32i32, *v.get(&7i32).unwrap()); // not updated!
});
@ -618,7 +618,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
let mut key_sum = 0;
let mut value_sum = 0;
@ -640,7 +640,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
let mut key_sum = 0;
for el in dict.keys().iter() {
@ -658,7 +658,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
let mut values_sum = 0;
for el in dict.values().iter() {
@ -676,7 +676,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
let mut key_sum = 0;
let mut value_sum = 0;
for (key, value) in dict.iter() {
@ -697,7 +697,7 @@ mod tests {
v.insert(9, 123);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
for (key, value) in dict.iter() {
dict.set_item(key, value.extract::<i32>().unwrap() + 7)
@ -715,7 +715,7 @@ mod tests {
v.insert(i * 2, i * 2);
}
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
for (i, (key, value)) in dict.iter().enumerate() {
let key = key.extract::<i32>().unwrap();
@ -740,7 +740,7 @@ mod tests {
v.insert(i * 2, i * 2);
}
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
for (i, (key, value)) in dict.iter().enumerate() {
let key = key.extract::<i32>().unwrap();
@ -764,7 +764,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
let mut iter = dict.iter();
assert_eq!(iter.size_hint(), (v.len(), Some(v.len())));
@ -790,7 +790,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let dict = <PyDict as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let dict: &PyDict = ob.downcast(py).unwrap();
let mut key_sum = 0;
let mut value_sum = 0;
for (key, value) in dict {

View File

@ -78,7 +78,7 @@ impl<'v> PyTryFrom<'v> for PyIterator {
}
fn try_from_exact<V: Into<&'v PyAny>>(value: V) -> Result<&'v PyIterator, PyDowncastError<'v>> {
<PyIterator as PyTryFrom>::try_from(value)
value.into().downcast()
}
#[inline]
@ -110,8 +110,6 @@ mod tests {
use crate::exceptions::PyTypeError;
use crate::gil::GILPool;
use crate::types::{PyDict, PyList};
#[cfg(any(not(Py_LIMITED_API), Py_3_8))]
use crate::PyTryFrom;
use crate::{Py, PyAny, Python, ToPyObject};
#[test]
@ -224,8 +222,7 @@ def fibonacci(target):
fn iterator_try_from() {
Python::with_gil(|py| {
let obj: Py<PyAny> = vec![10, 20].to_object(py).as_ref(py).iter().unwrap().into();
let iter: &PyIterator =
<PyIterator as PyTryFrom<'_>>::try_from(obj.as_ref(py)).unwrap();
let iter: &PyIterator = obj.downcast(py).unwrap();
assert!(obj.is(iter));
});
}

View File

@ -343,7 +343,7 @@ impl<'a> std::iter::IntoIterator for &'a PyList {
mod tests {
use crate::types::PyList;
use crate::Python;
use crate::{IntoPy, PyObject, PyTryFrom, ToPyObject};
use crate::{IntoPy, PyObject, ToPyObject};
#[test]
fn test_new() {
@ -407,7 +407,7 @@ mod tests {
let _pool = unsafe { crate::GILPool::new() };
let v = vec![2];
let ob = v.to_object(py);
let list = <PyList as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let list: &PyList = ob.downcast(py).unwrap();
let none = py.None();
cnt = none.get_refcnt(py);
list.set_item(0, none).unwrap();
@ -494,7 +494,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec![2, 3, 5, 7];
let ob = v.to_object(py);
let list = <PyList as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let list: &PyList = ob.downcast(py).unwrap();
let mut iter = list.iter();
assert_eq!(iter.size_hint(), (v.len(), Some(v.len())));
@ -566,7 +566,7 @@ mod tests {
fn test_array_into_py() {
Python::with_gil(|py| {
let array: PyObject = [1, 2].into_py(py);
let list = <PyList as PyTryFrom>::try_from(array.as_ref(py)).unwrap();
let list: &PyList = array.downcast(py).unwrap();
assert_eq!(1, list[0].extract::<i32>().unwrap());
assert_eq!(2, list[1].extract::<i32>().unwrap());
});

View File

@ -151,7 +151,7 @@ impl<'v> PyTryFrom<'v> for PyMapping {
#[inline]
fn try_from_exact<V: Into<&'v PyAny>>(value: V) -> Result<&'v PyMapping, PyDowncastError<'v>> {
<PyMapping as PyTryFrom>::try_from(value)
value.into().downcast()
}
#[inline]
@ -194,13 +194,13 @@ mod tests {
Python::with_gil(|py| {
let mut v = HashMap::new();
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
assert_eq!(0, mapping.len().unwrap());
assert!(mapping.is_empty().unwrap());
v.insert(7, 32);
let ob = v.to_object(py);
let mapping2 = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping2: &PyMapping = ob.downcast(py).unwrap();
assert_eq!(1, mapping2.len().unwrap());
assert!(!mapping2.is_empty().unwrap());
});
@ -212,7 +212,7 @@ mod tests {
let mut v = HashMap::new();
v.insert("key0", 1234);
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
mapping.set_item("key1", "foo").unwrap();
assert!(mapping.contains("key0").unwrap());
@ -227,7 +227,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
assert_eq!(
32,
mapping.get_item(7i32).unwrap().extract::<i32>().unwrap()
@ -245,7 +245,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
assert!(mapping.set_item(7i32, 42i32).is_ok()); // change
assert!(mapping.set_item(8i32, 123i32).is_ok()); // insert
assert_eq!(
@ -265,7 +265,7 @@ mod tests {
let mut v = HashMap::new();
v.insert(7, 32);
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
assert!(mapping.del_item(7i32).is_ok());
assert_eq!(0, mapping.len().unwrap());
assert!(mapping
@ -283,7 +283,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
let mut key_sum = 0;
let mut value_sum = 0;
@ -305,7 +305,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
let mut key_sum = 0;
for el in mapping.keys().unwrap().iter().unwrap() {
@ -323,7 +323,7 @@ mod tests {
v.insert(8, 42);
v.insert(9, 123);
let ob = v.to_object(py);
let mapping = <PyMapping as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let mapping: &PyMapping = ob.downcast(py).unwrap();
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
let mut values_sum = 0;
for el in mapping.values().unwrap().iter().unwrap() {

View File

@ -213,7 +213,7 @@ macro_rules! pyobject_native_type_extract {
($name:ty $(;$generics:ident)*) => {
impl<'py, $($generics,)*> $crate::FromPyObject<'py> for &'py $name {
fn extract(obj: &'py $crate::PyAny) -> $crate::PyResult<Self> {
$crate::PyTryFrom::try_from(obj).map_err(::std::convert::Into::into)
obj.downcast().map_err(::std::convert::Into::into)
}
}
}

View File

@ -347,7 +347,7 @@ impl<'v> PyTryFrom<'v> for PySequence {
}
fn try_from_exact<V: Into<&'v PyAny>>(value: V) -> Result<&'v PySequence, PyDowncastError<'v>> {
<PySequence as PyTryFrom>::try_from(value)
value.into().downcast()
}
#[inline]
@ -401,7 +401,7 @@ mod tests {
fn test_numbers_are_not_sequences() {
Python::with_gil(|py| {
let v = 42i32;
assert!(<PySequence as PyTryFrom>::try_from(v.to_object(py).as_ref(py)).is_err());
assert!(v.to_object(py).downcast::<PySequence>(py).is_err());
});
}
@ -409,7 +409,7 @@ mod tests {
fn test_strings_are_sequences() {
Python::with_gil(|py| {
let v = "London Calling";
assert!(<PySequence as PyTryFrom>::try_from(v.to_object(py).as_ref(py)).is_ok());
assert!(v.to_object(py).downcast::<PySequence>(py).is_ok());
});
}
@ -809,7 +809,7 @@ mod tests {
Python::with_gil(|py| {
let v = "foo";
let ob = v.to_object(py);
let seq = <PySequence as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let seq: &PySequence = ob.downcast(py).unwrap();
assert!(seq.list().is_ok());
});
}

View File

@ -233,7 +233,7 @@ pub use impl_::*;
#[cfg(test)]
mod tests {
use super::PySet;
use crate::{PyTryFrom, Python, ToPyObject};
use crate::{Python, ToPyObject};
use std::collections::HashSet;
#[test]
@ -260,11 +260,11 @@ mod tests {
Python::with_gil(|py| {
let mut v = HashSet::new();
let ob = v.to_object(py);
let set = <PySet as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let set: &PySet = ob.downcast(py).unwrap();
assert_eq!(0, set.len());
v.insert(7);
let ob = v.to_object(py);
let set2 = <PySet as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let set2: &PySet = ob.downcast(py).unwrap();
assert_eq!(1, set2.len());
});
}

View File

@ -285,7 +285,7 @@ mod tests {
#[cfg(all(not(Py_LIMITED_API), target_endian = "little"))]
use crate::PyTypeInfo;
use crate::Python;
use crate::{PyObject, PyTryFrom, ToPyObject};
use crate::{PyObject, ToPyObject};
#[cfg(all(not(Py_LIMITED_API), target_endian = "little"))]
use std::borrow::Cow;
@ -294,7 +294,7 @@ mod tests {
Python::with_gil(|py| {
let s = "ascii 🐈";
let obj: PyObject = PyString::new(py, s).into();
let py_string = <PyString as PyTryFrom>::try_from(obj.as_ref(py)).unwrap();
let py_string: &PyString = obj.downcast(py).unwrap();
assert_eq!(s, py_string.to_str().unwrap());
})
}
@ -303,7 +303,7 @@ mod tests {
fn test_to_str_surrogate() {
Python::with_gil(|py| {
let obj: PyObject = py.eval(r#"'\ud800'"#, None, None).unwrap().into();
let py_string = <PyString as PyTryFrom>::try_from(obj.as_ref(py)).unwrap();
let py_string: &PyString = obj.downcast(py).unwrap();
assert!(py_string.to_str().is_err());
})
}
@ -313,7 +313,7 @@ mod tests {
Python::with_gil(|py| {
let s = "哈哈🐈";
let obj: PyObject = PyString::new(py, s).into();
let py_string = <PyString as PyTryFrom>::try_from(obj.as_ref(py)).unwrap();
let py_string: &PyString = obj.downcast(py).unwrap();
assert_eq!(s, py_string.to_str().unwrap());
})
}
@ -325,7 +325,7 @@ mod tests {
.eval(r#"'🐈 Hello \ud800World'"#, None, None)
.unwrap()
.into();
let py_string = <PyString as PyTryFrom>::try_from(obj.as_ref(py)).unwrap();
let py_string: &PyString = obj.downcast(py).unwrap();
assert_eq!(py_string.to_string_lossy(), "🐈 Hello <20><><EFBFBD>World");
})
}
@ -334,7 +334,7 @@ mod tests {
fn test_debug_string() {
Python::with_gil(|py| {
let v = "Hello\n".to_object(py);
let s = <PyString as PyTryFrom>::try_from(v.as_ref(py)).unwrap();
let s: &PyString = v.downcast(py).unwrap();
assert_eq!(format!("{:?}", s), "'Hello\\n'");
})
}
@ -343,7 +343,7 @@ mod tests {
fn test_display_string() {
Python::with_gil(|py| {
let v = "Hello\n".to_object(py);
let s = <PyString as PyTryFrom>::try_from(v.as_ref(py)).unwrap();
let s: &PyString = v.downcast(py).unwrap();
assert_eq!(format!("{}", s), "Hello\n");
})
}

View File

@ -145,7 +145,7 @@ impl PyTuple {
/// # fn main() -> PyResult<()> {
/// Python::with_gil(|py| -> PyResult<()> {
/// let ob = (1, 2, 3).to_object(py);
/// let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
/// let tuple: &PyTuple = ob.downcast(py).unwrap();
/// let obj = tuple.get_item(0);
/// assert_eq!(obj.unwrap().extract::<i32>().unwrap(), 1);
/// Ok(())
@ -316,7 +316,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
impl<'s, $($T: FromPyObject<'s>),+> FromPyObject<'s> for ($($T,)+) {
fn extract(obj: &'s PyAny) -> PyResult<Self>
{
let t = <PyTuple as PyTryFrom>::try_from(obj)?;
let t: &PyTuple = obj.downcast()?;
if t.len() == $length {
#[cfg(any(Py_LIMITED_API, PyPy))]
return Ok(($(t.get_item($n)?.extract::<$T>()?,)+));
@ -441,7 +441,7 @@ tuple_conversion!(
#[cfg(test)]
mod tests {
use crate::types::{PyAny, PyTuple};
use crate::{PyTryFrom, Python, ToPyObject};
use crate::{Python, ToPyObject};
use std::collections::HashSet;
#[test]
@ -463,7 +463,7 @@ mod tests {
fn test_len() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
assert_eq!(3, tuple.len());
let ob: &PyAny = tuple.into();
assert_eq!((1, 2, 3), ob.extract().unwrap());
@ -485,7 +485,7 @@ mod tests {
fn test_iter() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
assert_eq!(3, tuple.len());
let mut iter = tuple.iter();
@ -506,7 +506,7 @@ mod tests {
fn test_into_iter() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
assert_eq!(3, tuple.len());
for (i, item) in tuple.iter().enumerate() {
@ -520,7 +520,7 @@ mod tests {
fn test_as_slice() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
let slice = tuple.as_slice();
assert_eq!(3, slice.len());
@ -598,7 +598,7 @@ mod tests {
fn test_tuple_get_item_invalid_index() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
let obj = tuple.get_item(5);
assert!(obj.is_err());
assert_eq!(
@ -612,7 +612,7 @@ mod tests {
fn test_tuple_get_item_sanity() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
let obj = tuple.get_item(0);
assert_eq!(obj.unwrap().extract::<i32>().unwrap(), 1);
});
@ -623,7 +623,7 @@ mod tests {
fn test_tuple_get_item_unchecked_sanity() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
let obj = unsafe { tuple.get_item_unchecked(0) };
assert_eq!(obj.extract::<i32>().unwrap(), 1);
});
@ -633,7 +633,7 @@ mod tests {
fn test_tuple_index_trait() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
assert_eq!(1, tuple[0].extract::<i32>().unwrap());
assert_eq!(2, tuple[1].extract::<i32>().unwrap());
assert_eq!(3, tuple[2].extract::<i32>().unwrap());
@ -645,7 +645,7 @@ mod tests {
fn test_tuple_index_trait_panic() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
let _ = &tuple[7];
});
}
@ -654,7 +654,7 @@ mod tests {
fn test_tuple_index_trait_ranges() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
assert_eq!(vec![2, 3], tuple[1..3].extract::<Vec<i32>>().unwrap());
assert_eq!(
Vec::<i32>::new(),
@ -674,7 +674,7 @@ mod tests {
fn test_tuple_index_trait_range_panic_start() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
tuple[5..10].extract::<Vec<i32>>().unwrap();
})
}
@ -684,7 +684,7 @@ mod tests {
fn test_tuple_index_trait_range_panic_end() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
tuple[1..10].extract::<Vec<i32>>().unwrap();
})
}
@ -694,7 +694,7 @@ mod tests {
fn test_tuple_index_trait_range_panic_wrong_order() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
#[allow(clippy::reversed_empty_ranges)]
tuple[2..1].extract::<Vec<i32>>().unwrap();
})
@ -705,7 +705,7 @@ mod tests {
fn test_tuple_index_trait_range_from_panic() {
Python::with_gil(|py| {
let ob = (1, 2, 3).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
tuple[8..].extract::<Vec<i32>>().unwrap();
})
}
@ -714,7 +714,7 @@ mod tests {
fn test_tuple_contains() {
Python::with_gil(|py| {
let ob = (1, 1, 2, 3, 5, 8).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
assert_eq!(6, tuple.len());
let bad_needle = 7i32.to_object(py);
@ -732,7 +732,7 @@ mod tests {
fn test_tuple_index() {
Python::with_gil(|py| {
let ob = (1, 1, 2, 3, 5, 8).to_object(py);
let tuple = <PyTuple as PyTryFrom>::try_from(ob.as_ref(py)).unwrap();
let tuple: &PyTuple = ob.downcast(py).unwrap();
assert_eq!(0, tuple.index(1i32).unwrap());
assert_eq!(2, tuple.index(2i32).unwrap());
assert_eq!(3, tuple.index(3i32).unwrap());