pyany: add is_instance
This commit is contained in:
parent
db78cd76c8
commit
fc34e41163
|
@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- Add FFI definitions for PEP 587 "Python Initialization Configuration". [#1247](https://github.com/PyO3/pyo3/pull/1247)
|
||||
- Add `PyEval_SetProfile` and `PyEval_SetTrace` to FFI. [#1255](https://github.com/PyO3/pyo3/pull/1255)
|
||||
- Add context.h functions (`PyContext_New`, etc) to FFI. [#1259](https://github.com/PyO3/pyo3/pull/1259)
|
||||
- Add `PyAny::is_instance()` method. [#1276](https://github.com/PyO3/pyo3/pull/1276)
|
||||
- Add support for conversion between `char` and `PyString`. [#1282](https://github.com/PyO3/pyo3/pull/1282)
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -96,8 +96,8 @@ fn my_func(arg: PyObject) -> PyResult<()> {
|
|||
|
||||
## Checking exception types
|
||||
|
||||
Python has an [`isinstance`](https://docs.python.org/3/library/functions.html#isinstance) method to check an object's type,
|
||||
in PyO3 there is a [`Python::is_instance`] method which does the same thing.
|
||||
Python has an [`isinstance`](https://docs.python.org/3/library/functions.html#isinstance) method to check an object's type.
|
||||
In PyO3 every native type has access to the [`PyAny::is_instance`] method which does the same thing.
|
||||
|
||||
```rust
|
||||
use pyo3::Python;
|
||||
|
@ -106,13 +106,13 @@ use pyo3::types::{PyBool, PyList};
|
|||
fn main() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
assert!(py.is_instance::<PyBool, _>(PyBool::new(py, true)).unwrap());
|
||||
assert!(PyBool::new(py, true).is_instance::<PyBool>().unwrap());
|
||||
let list = PyList::new(py, &[1, 2, 3, 4]);
|
||||
assert!(!py.is_instance::<PyBool, _>(list.as_ref()).unwrap());
|
||||
assert!(py.is_instance::<PyList, _>(list.as_ref()).unwrap());
|
||||
assert!(!list.is_instance::<PyBool>().unwrap());
|
||||
assert!(list.is_instance::<PyList>().unwrap());
|
||||
}
|
||||
```
|
||||
[`Python::is_instance`] calls the underlying [`PyType::is_instance`](https://docs.rs/pyo3/latest/pyo3/types/struct.PyType.html#method.is_instance)
|
||||
[`PyAny::is_instance`] calls the underlying [`PyType::is_instance`](https://docs.rs/pyo3/latest/pyo3/types/struct.PyType.html#method.is_instance)
|
||||
method to do the actual work.
|
||||
|
||||
To check the type of an exception, you can similarly do:
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::conversion::{
|
|||
};
|
||||
use crate::err::{PyDowncastError, PyErr, PyResult};
|
||||
use crate::exceptions::PyTypeError;
|
||||
use crate::type_object::PyTypeObject;
|
||||
use crate::types::{PyDict, PyIterator, PyList, PyString, PyTuple, PyType};
|
||||
use crate::{err, ffi, Py, PyNativeType, PyObject};
|
||||
use libc::c_int;
|
||||
|
@ -29,8 +30,8 @@ use std::cmp::Ordering;
|
|||
/// use pyo3::types::{PyAny, PyDict, PyList};
|
||||
/// let gil = Python::acquire_gil();
|
||||
/// let dict = PyDict::new(gil.python());
|
||||
/// assert!(gil.python().is_instance::<PyAny, _>(dict).unwrap());
|
||||
/// let any = dict.as_ref();
|
||||
/// assert!(dict.is_instance::<PyAny>().unwrap());
|
||||
/// let any: &PyAny = dict.as_ref();
|
||||
/// assert!(any.downcast::<PyDict>().is_ok());
|
||||
/// assert!(any.downcast::<PyList>().is_err());
|
||||
/// ```
|
||||
|
@ -452,13 +453,19 @@ impl PyAny {
|
|||
pub fn dir(&self) -> &PyList {
|
||||
unsafe { self.py().from_owned_ptr(ffi::PyObject_Dir(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Checks whether this object is an instance of type `T`.
|
||||
///
|
||||
/// This is equivalent to the Python expression `isinstance(self, T)`.
|
||||
pub fn is_instance<T: PyTypeObject>(&self) -> PyResult<bool> {
|
||||
T::type_object(self.py()).is_instance(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::types::{IntoPyDict, PyList};
|
||||
use crate::Python;
|
||||
use crate::ToPyObject;
|
||||
use crate::types::{IntoPyDict, PyList, PyLong};
|
||||
use crate::{Python, ToPyObject};
|
||||
|
||||
#[test]
|
||||
fn test_call_for_non_existing_method() {
|
||||
|
@ -514,4 +521,16 @@ mod test {
|
|||
let nan = py.eval("float('nan')", None, None).unwrap();
|
||||
assert!(nan.compare(nan).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_any_isinstance() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let x = 5.to_object(py).into_ref(py);
|
||||
assert!(x.is_instance::<PyLong>().unwrap());
|
||||
|
||||
let l = vec![x, x].to_object(py).into_ref(py);
|
||||
assert!(l.is_instance::<PyList>().unwrap());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue