Py/PyAny: deprecate cast_as() in favor of downcast()

They are (practically) identical on PyAny, and `downcast()` is the more
useful name.
This commit is contained in:
Georg Brandl 2022-11-14 07:15:33 +01:00
parent 1d20f2a531
commit c489809938
15 changed files with 96 additions and 83 deletions

View file

@ -21,12 +21,12 @@ fn enum_from_pyobject(b: &mut Bencher<'_>) {
})
}
fn list_via_cast_as(b: &mut Bencher<'_>) {
fn list_via_downcast(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &PyAny = PyList::empty(py).into();
b.iter(|| {
let _list: &PyList = black_box(any).cast_as().unwrap();
let _list: &PyList = black_box(any).downcast().unwrap();
});
})
}
@ -41,12 +41,12 @@ fn list_via_extract(b: &mut Bencher<'_>) {
})
}
fn not_a_list_via_cast_as(b: &mut Bencher<'_>) {
fn not_a_list_via_downcast(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let any: &PyAny = PyString::new(py, "foobar").into();
b.iter(|| {
black_box(any).cast_as::<PyList>().unwrap_err();
black_box(any).downcast::<PyList>().unwrap_err();
});
})
}
@ -81,9 +81,9 @@ fn not_a_list_via_extract_enum(b: &mut Bencher<'_>) {
fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("enum_from_pyobject", enum_from_pyobject);
c.bench_function("list_via_cast_as", list_via_cast_as);
c.bench_function("list_via_downcast", list_via_downcast);
c.bench_function("list_via_extract", list_via_extract);
c.bench_function("not_a_list_via_cast_as", not_a_list_via_cast_as);
c.bench_function("not_a_list_via_downcast", not_a_list_via_downcast);
c.bench_function("not_a_list_via_extract", not_a_list_via_extract);
c.bench_function("not_a_list_via_extract_enum", not_a_list_via_extract_enum);
}

View file

@ -321,7 +321,7 @@ fn main() -> PyResult<()> {
let path = Path::new("/usr/share/python_app");
let py_app = fs::read_to_string(path.join("app.py"))?;
let from_python = Python::with_gil(|py| -> PyResult<Py<PyAny>> {
let syspath: &PyList = py.import("sys")?.getattr("path")?.downcast::<PyList>()?;
let syspath: &PyList = py.import("sys")?.getattr("path")?.downcast()?;
syspath.insert(0, &path)?;
let app: Py<PyAny> = PyModule::from_code(py, &py_app, "", "")?
.getattr("run")?

View file

@ -0,0 +1 @@
Added `Py::downcast()` as a companion to `PyAny::downcast()`.

View file

@ -0,0 +1,2 @@
`PyAny::cast_as()` and `Py::cast_as()` are now deprecated in favor of
`PyAny::downcast()` and the new `Py::downcast()`.

View file

@ -36,7 +36,7 @@
//! Python::with_gil(|py| {
//! // Create an UTC datetime in python
//! let py_tz = Utc.to_object(py);
//! let py_tz = py_tz.cast_as(py).unwrap();
//! let py_tz = py_tz.downcast(py).unwrap();
//! let pydatetime = PyDateTime::new(py, 2022, 1, 1, 12, 0, 0, 0, Some(py_tz)).unwrap();
//! println!("PyDateTime: {}", pydatetime);
//! // Now convert it to chrono's DateTime<Utc>
@ -237,7 +237,7 @@ impl<Tz: TimeZone> ToPyObject for DateTime<Tz> {
None => (ns / 1000, false),
};
let tz = self.offset().fix().to_object(py);
let tz = tz.cast_as(py).unwrap();
let tz = tz.downcast(py).unwrap();
let datetime = PyDateTime::new_with_fold(py, yy, mm, dd, h, m, s, ms, Some(tz), fold)
.expect("Failed to construct datetime");
datetime.into()
@ -577,7 +577,7 @@ mod tests {
let datetime = DateTime::<Utc>::from_utc(datetime, Utc).to_object(py);
let datetime: &PyDateTime = datetime.extract(py).unwrap();
let py_tz = Utc.to_object(py);
let py_tz = py_tz.cast_as(py).unwrap();
let py_tz = py_tz.downcast(py).unwrap();
let py_datetime = PyDateTime::new_with_fold(
py,
year,
@ -617,7 +617,7 @@ mod tests {
DateTime::<FixedOffset>::from_utc(datetime, offset).to_object(py);
let datetime: &PyDateTime = datetime.extract(py).unwrap();
let py_tz = offset.to_object(py);
let py_tz = py_tz.cast_as(py).unwrap();
let py_tz = py_tz.downcast(py).unwrap();
let py_datetime = PyDateTime::new_with_fold(
py,
year,
@ -652,7 +652,7 @@ mod tests {
|name: &'static str, year, month, day, hour, minute, second, ms, py_ms, fold| {
Python::with_gil(|py| {
let py_tz = Utc.to_object(py);
let py_tz = py_tz.cast_as(py).unwrap();
let py_tz = py_tz.downcast(py).unwrap();
let py_datetime = PyDateTime::new_with_fold(
py,
year,
@ -688,7 +688,7 @@ mod tests {
Python::with_gil(|py| {
let offset = FixedOffset::east_opt(3600).unwrap();
let py_tz = offset.to_object(py);
let py_tz = py_tz.cast_as(py).unwrap();
let py_tz = py_tz.downcast(py).unwrap();
let py_datetime = PyDateTime::new_with_fold(
py,
year,
@ -721,14 +721,14 @@ mod tests {
Python::with_gil(|py| {
let py_tz = Utc.to_object(py);
let py_tz = py_tz.cast_as(py).unwrap();
let py_tz = py_tz.downcast(py).unwrap();
let py_datetime =
PyDateTime::new_with_fold(py, 2014, 5, 6, 7, 8, 9, 999_999, Some(py_tz), false)
.unwrap();
assert!(py_datetime.extract::<DateTime<FixedOffset>>().is_ok());
let offset = FixedOffset::east_opt(3600).unwrap();
let py_tz = offset.to_object(py);
let py_tz = py_tz.cast_as(py).unwrap();
let py_tz = py_tz.downcast(py).unwrap();
let py_datetime =
PyDateTime::new_with_fold(py, 2014, 5, 6, 7, 8, 9, 999_999, Some(py_tz), false)
.unwrap();

View file

@ -386,7 +386,7 @@ mod tests {
Python::with_gil(|py| {
let array: [Foo; 8] = [Foo, Foo, Foo, Foo, Foo, Foo, Foo, Foo];
let pyobject = array.into_py(py);
let list: &PyList = pyobject.cast_as(py).unwrap();
let list: &PyList = pyobject.downcast(py).unwrap();
let _cell: &crate::PyCell<Foo> = list.get_item(4).unwrap().extract().unwrap();
});
}

View file

@ -995,11 +995,20 @@ impl PyObject {
///
/// This can cast only to native Python types, not types implemented in Rust. For a more
/// flexible alternative, see [`Py::extract`](struct.Py.html#method.extract).
pub fn downcast<'p, T>(&'p self, py: Python<'p>) -> Result<&T, PyDowncastError<'_>>
where
for<'py> T: PyTryFrom<'py>,
{
<T as PyTryFrom<'_>>::try_from(self.as_ref(py))
}
/// Casts the PyObject to a concrete Python object type.
#[deprecated(since = "0.18.0", note = "use downcast() instead")]
pub fn cast_as<'p, D>(&'p self, py: Python<'p>) -> Result<&'p D, PyDowncastError<'_>>
where
D: PyTryFrom<'p>,
{
<D as PyTryFrom<'_>>::try_from(unsafe { py.from_borrowed_ptr::<PyAny>(self.as_ptr()) })
<D as PyTryFrom<'_>>::try_from(self.as_ref(py))
}
}

View file

@ -64,29 +64,6 @@ pyobject_native_type_extract!(PyAny);
pyobject_native_type_sized!(PyAny, ffi::PyObject);
impl PyAny {
/// Converts this `PyAny` to a concrete Python type.
///
/// # Examples
///
/// ```rust
/// use pyo3::prelude::*;
/// use pyo3::types::{PyAny, PyDict, PyList};
///
/// Python::with_gil(|py| {
/// let dict = PyDict::new(py);
/// assert!(dict.is_instance_of::<PyAny>().unwrap());
/// let any: &PyAny = dict.as_ref();
/// assert!(any.downcast::<PyDict>().is_ok());
/// assert!(any.downcast::<PyList>().is_err());
/// });
/// ```
pub fn downcast<T>(&self) -> Result<&T, PyDowncastError<'_>>
where
for<'py> T: PyTryFrom<'py>,
{
<T as PyTryFrom>::try_from(self)
}
/// Returns whether `self` and `other` point to the same object. To compare
/// the equality of two objects (the `==` operator), use [`eq`](PyAny::eq).
///
@ -769,9 +746,8 @@ impl PyAny {
unsafe { ffi::Py_TYPE(self.as_ptr()) }
}
/// Casts `self` to a concrete Python object type.
///
/// This can cast only to native Python types, not types implemented in Rust.
/// Converts this `PyAny` to a concrete Python type.
#[deprecated(since = "0.18.0", note = "use the equivalent .downcast()")]
pub fn cast_as<'a, D>(&'a self) -> Result<&'a D, PyDowncastError<'_>>
where
D: PyTryFrom<'a>,
@ -779,6 +755,31 @@ impl PyAny {
<D as PyTryFrom<'_>>::try_from(self)
}
/// Converts this `PyAny` to a concrete Python type.
///
/// This can cast only to native Python types, not types implemented in Rust.
///
/// # Examples
///
/// ```rust
/// use pyo3::prelude::*;
/// use pyo3::types::{PyAny, PyDict, PyList};
///
/// Python::with_gil(|py| {
/// let dict = PyDict::new(py);
/// assert!(dict.is_instance_of::<PyAny>().unwrap());
/// let any: &PyAny = dict.as_ref();
/// assert!(any.downcast::<PyDict>().is_ok());
/// assert!(any.downcast::<PyList>().is_err());
/// });
/// ```
pub fn downcast<T>(&self) -> Result<&T, PyDowncastError<'_>>
where
for<'py> T: PyTryFrom<'py>,
{
<T as PyTryFrom>::try_from(self)
}
/// Extracts some type from the Python object.
///
/// This is a wrapper function around [`FromPyObject::extract()`].

View file

@ -623,7 +623,7 @@ mod tests {
let mut key_sum = 0;
let mut value_sum = 0;
for el in dict.items().iter() {
let tuple = el.cast_as::<PyTuple>().unwrap();
let tuple = el.downcast::<PyTuple>().unwrap();
key_sum += tuple.get_item(0).unwrap().extract::<i32>().unwrap();
value_sum += tuple.get_item(1).unwrap().extract::<i32>().unwrap();
}

View file

@ -288,7 +288,7 @@ mod tests {
let mut key_sum = 0;
let mut value_sum = 0;
for el in mapping.items().unwrap().iter().unwrap() {
let tuple = el.unwrap().cast_as::<PyTuple>().unwrap();
let tuple = el.unwrap().downcast::<PyTuple>().unwrap();
key_sum += tuple.get_item(0).unwrap().extract::<i32>().unwrap();
value_sum += tuple.get_item(1).unwrap().extract::<i32>().unwrap();
}

View file

@ -57,7 +57,7 @@ pub use self::typeobject::PyType;
///
/// # pub fn main() -> PyResult<()> {
/// Python::with_gil(|py| {
/// let dict: &PyDict = py.eval("{'a':'b', 'c':'d'}", None, None)?.cast_as()?;
/// let dict: &PyDict = py.eval("{'a':'b', 'c':'d'}", None, None)?.downcast()?;
///
/// for (key, value) in dict {
/// println!("key: {}, value: {}", key, value);

View file

@ -430,7 +430,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(0, seq.len().unwrap());
let needle = 7i32.to_object(py);
@ -442,11 +442,11 @@ mod tests {
fn test_seq_is_empty() {
Python::with_gil(|py| {
let list = vec![1].to_object(py);
let seq = list.cast_as::<PySequence>(py).unwrap();
let seq = list.downcast::<PySequence>(py).unwrap();
assert!(!seq.is_empty().unwrap());
let vec: Vec<u32> = Vec::new();
let empty_list = vec.to_object(py);
let empty_seq = empty_list.cast_as::<PySequence>(py).unwrap();
let empty_seq = empty_list.downcast::<PySequence>(py).unwrap();
assert!(empty_seq.is_empty().unwrap());
});
}
@ -456,7 +456,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(6, seq.len().unwrap());
let bad_needle = 7i32.to_object(py);
@ -475,7 +475,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(1, seq.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(1, seq.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(2, seq.get_item(2).unwrap().extract::<i32>().unwrap());
@ -491,7 +491,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(1, seq[0].extract::<i32>().unwrap());
assert_eq!(1, seq[1].extract::<i32>().unwrap());
assert_eq!(2, seq[2].extract::<i32>().unwrap());
@ -504,7 +504,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let _ = &seq[7];
});
}
@ -514,7 +514,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(vec![1, 2], seq[1..3].extract::<Vec<i32>>().unwrap());
assert_eq!(Vec::<i32>::new(), seq[3..3].extract::<Vec<i32>>().unwrap());
assert_eq!(vec![1, 2], seq[1..].extract::<Vec<i32>>().unwrap());
@ -532,7 +532,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
seq[5..10].extract::<Vec<i32>>().unwrap();
})
}
@ -543,7 +543,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
seq[1..10].extract::<Vec<i32>>().unwrap();
})
}
@ -554,7 +554,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
#[allow(clippy::reversed_empty_ranges)]
seq[2..1].extract::<Vec<i32>>().unwrap();
})
@ -566,7 +566,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
seq[8..].extract::<Vec<i32>>().unwrap();
})
}
@ -576,7 +576,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert!(seq.del_item(10).is_err());
assert_eq!(1, seq[0].extract::<i32>().unwrap());
assert!(seq.del_item(0).is_ok());
@ -600,7 +600,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(2, seq[1].extract::<i32>().unwrap());
assert!(seq.set_item(1, 10).is_ok());
assert_eq!(10, seq[1].extract::<i32>().unwrap());
@ -614,7 +614,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 2];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert!(seq.set_item(1, &obj).is_ok());
assert!(seq[1].as_ptr() == obj.as_ptr());
});
@ -629,7 +629,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(
[1, 2, 3],
seq.get_slice(1, 4).unwrap().extract::<[i32; 3]>().unwrap()
@ -650,7 +650,7 @@ mod tests {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let w: Vec<i32> = vec![7, 4];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let ins = w.to_object(py);
seq.set_slice(1, 4, ins.as_ref(py)).unwrap();
assert_eq!([1, 7, 4, 5, 8], seq.extract::<[i32; 5]>().unwrap());
@ -664,7 +664,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
seq.del_slice(1, 4).unwrap();
assert_eq!([1, 5, 8], seq.extract::<[i32; 3]>().unwrap());
seq.del_slice(1, 100).unwrap();
@ -677,7 +677,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(0, seq.index(1i32).unwrap());
assert_eq!(2, seq.index(2i32).unwrap());
assert_eq!(3, seq.index(3i32).unwrap());
@ -693,7 +693,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert_eq!(2, seq.count(1i32).unwrap());
assert_eq!(1, seq.count(2i32).unwrap());
assert_eq!(1, seq.count(3i32).unwrap());
@ -708,7 +708,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let mut idx = 0;
for el in seq.iter().unwrap() {
assert_eq!(v[idx], el.unwrap().extract::<i32>().unwrap());
@ -723,7 +723,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec!["It", "was", "the", "worst", "of", "times"];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let bad_needle = "blurst".to_object(py);
assert!(!seq.contains(bad_needle).unwrap());
@ -738,7 +738,7 @@ mod tests {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 2, 3];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let concat_seq = seq.concat(seq).unwrap();
assert_eq!(6, concat_seq.len().unwrap());
let concat_v: Vec<i32> = vec![1, 2, 3, 1, 2, 3];
@ -753,7 +753,7 @@ mod tests {
Python::with_gil(|py| {
let v = "string";
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let concat_seq = seq.concat(seq).unwrap();
assert_eq!(12, concat_seq.len().unwrap());
let concat_v = "stringstring".to_owned();
@ -768,7 +768,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec!["foo", "bar"];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let repeat_seq = seq.repeat(3).unwrap();
assert_eq!(6, repeat_seq.len().unwrap());
let repeated = vec!["foo", "bar", "foo", "bar", "foo", "bar"];
@ -783,7 +783,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec!["foo", "bar"];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let rep_seq = seq.in_place_repeat(3).unwrap();
assert_eq!(6, seq.len().unwrap());
assert!(seq.is(rep_seq));
@ -799,7 +799,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec!["foo", "bar"];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert!(seq.list().is_ok());
});
}
@ -819,7 +819,7 @@ mod tests {
Python::with_gil(|py| {
let v = ("foo", "bar");
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert!(seq.tuple().is_ok());
});
}
@ -829,7 +829,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec!["foo", "bar"];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
assert!(seq.tuple().is_ok());
});
}
@ -871,7 +871,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec!["foo", "bar"];
let ob = v.to_object(py);
let seq = ob.cast_as::<PySequence>(py).unwrap();
let seq = ob.downcast::<PySequence>(py).unwrap();
let type_ptr = seq.as_ref();
let seq_from = unsafe { <PySequence as PyTryFrom>::try_from_unchecked(type_ptr) };
assert!(seq_from.list().is_ok());

View file

@ -392,7 +392,7 @@ mod tests {
fn test_string_data_ucs2() {
Python::with_gil(|py| {
let s = py.eval("'foo\\ud800'", None, None).unwrap();
let py_string = s.cast_as::<PyString>().unwrap();
let py_string = s.downcast::<PyString>().unwrap();
let data = unsafe { py_string.data().unwrap() };
assert_eq!(data, PyStringData::Ucs2(&[102, 111, 111, 0xd800]));

View file

@ -21,7 +21,7 @@ fn empty_class_with_new() {
assert!(typeobj
.call((), None)
.unwrap()
.cast_as::<PyCell<EmptyClassWithNew>>()
.downcast::<PyCell<EmptyClassWithNew>>()
.is_ok());
});
}
@ -44,7 +44,7 @@ fn unit_class_with_new() {
assert!(typeobj
.call((), None)
.unwrap()
.cast_as::<PyCell<UnitClassWithNew>>()
.downcast::<PyCell<UnitClassWithNew>>()
.is_ok());
});
}
@ -65,7 +65,7 @@ fn tuple_class_with_new() {
Python::with_gil(|py| {
let typeobj = py.get_type::<TupleClassWithNew>();
let wrp = typeobj.call((42,), None).unwrap();
let obj = wrp.cast_as::<PyCell<TupleClassWithNew>>().unwrap();
let obj = wrp.downcast::<PyCell<TupleClassWithNew>>().unwrap();
let obj_ref = obj.borrow();
assert_eq!(obj_ref.0, 42);
});
@ -90,7 +90,7 @@ fn new_with_one_arg() {
Python::with_gil(|py| {
let typeobj = py.get_type::<NewWithOneArg>();
let wrp = typeobj.call((42,), None).unwrap();
let obj = wrp.cast_as::<PyCell<NewWithOneArg>>().unwrap();
let obj = wrp.downcast::<PyCell<NewWithOneArg>>().unwrap();
let obj_ref = obj.borrow();
assert_eq!(obj_ref._data, 42);
});
@ -121,7 +121,7 @@ fn new_with_two_args() {
.call((10, 20), None)
.map_err(|e| e.print(py))
.unwrap();
let obj = wrp.cast_as::<PyCell<NewWithTwoArgs>>().unwrap();
let obj = wrp.downcast::<PyCell<NewWithTwoArgs>>().unwrap();
let obj_ref = obj.borrow();
assert_eq!(obj_ref._data1, 10);
assert_eq!(obj_ref._data2, 20);

View file

@ -529,7 +529,7 @@ struct GetItem {}
#[pymethods]
impl GetItem {
fn __getitem__(&self, idx: &PyAny) -> PyResult<&'static str> {
if let Ok(slice) = idx.cast_as::<PySlice>() {
if let Ok(slice) = idx.downcast::<PySlice>() {
let indices = slice.indices(1000)?;
if indices.start == 100 && indices.stop == 200 && indices.step == 1 {
return Ok("slice");