Make `is_instance()` and `is_subclass()` take `&PyAny` (#2695)

This commit is contained in:
Georg Brandl 2022-10-18 19:22:23 +02:00 committed by GitHub
parent bec726c463
commit 676227d2a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 10 additions and 10 deletions

View File

@ -540,8 +540,6 @@ fn main() -> PyResult<()> {
uvloop
.as_ref(py)
.getattr("Loop")?
.downcast::<PyType>()
.unwrap()
)?);
Ok(())
})?;

View File

@ -0,0 +1,3 @@
`PyType::is_subclass`, `PyErr::is_instance` and `PyAny::is_instance` now take
`&PyAny` instead of `&PyType` arguments, so that they work with objects that
pretend to be types using `__subclasscheck__` and `__instancecheck__`.

View File

@ -1,5 +1,4 @@
use crate::intern;
use crate::types::PyType;
use crate::{FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
use std::borrow::Cow;
use std::ffi::OsString;
@ -20,7 +19,7 @@ impl FromPyObject<'_> for PathBuf {
Err(err) => {
let py = ob.py();
let pathlib = py.import(intern!(py, "pathlib"))?;
let pathlib_path: &PyType = pathlib.getattr(intern!(py, "Path"))?.downcast()?;
let pathlib_path = pathlib.getattr(intern!(py, "Path"))?;
if ob.is_instance(pathlib_path)? {
let path_str = ob.call_method0(intern!(py, "__str__"))?;
OsString::extract(path_str)?

View File

@ -448,8 +448,8 @@ impl PyErr {
/// Returns true if the current exception is instance of `T`.
#[inline]
pub fn is_instance(&self, py: Python<'_>, typ: &PyType) -> bool {
unsafe { ffi::PyErr_GivenExceptionMatches(self.type_ptr(py), typ.as_ptr()) != 0 }
pub fn is_instance(&self, py: Python<'_>, ty: &PyAny) -> bool {
unsafe { ffi::PyErr_GivenExceptionMatches(self.type_ptr(py), ty.as_ptr()) != 0 }
}
/// Returns true if the current exception is instance of `T`.

View File

@ -848,7 +848,7 @@ impl PyAny {
/// Checks whether this object is an instance of type `ty`.
///
/// This is equivalent to the Python expression `isinstance(self, ty)`.
pub fn is_instance(&self, ty: &PyType) -> PyResult<bool> {
pub fn is_instance(&self, ty: &PyAny) -> PyResult<bool> {
let result = unsafe { ffi::PyObject_IsInstance(self.as_ptr(), ty.as_ptr()) };
err::error_on_minusone(self.py(), result)?;
Ok(result == 1)
@ -985,7 +985,7 @@ class SimpleClass:
}
#[test]
fn test_any_isinstance() {
fn test_any_isinstance_of() {
Python::with_gil(|py| {
let x = 5.to_object(py).into_ref(py);
assert!(x.is_instance_of::<PyLong>().unwrap());
@ -996,7 +996,7 @@ class SimpleClass:
}
#[test]
fn test_any_isinstance_of() {
fn test_any_isinstance() {
Python::with_gil(|py| {
let l = vec![1u8, 2].to_object(py).into_ref(py);
assert!(l.is_instance(PyList::type_object(py)).unwrap());

View File

@ -42,7 +42,7 @@ impl PyType {
/// Checks whether `self` is a subclass of `other`.
///
/// Equivalent to the Python expression `issubclass(self, other)`.
pub fn is_subclass(&self, other: &PyType) -> PyResult<bool> {
pub fn is_subclass(&self, other: &PyAny) -> PyResult<bool> {
let result = unsafe { ffi::PyObject_IsSubclass(self.as_ptr(), other.as_ptr()) };
err::error_on_minusone(self.py(), result)?;
Ok(result == 1)