Skip to content

Commit

Permalink
Make is_instance() and is_subclass() take &PyAny
Browse files Browse the repository at this point in the history
Should be (mostly?) compatible since `&PyType` auto-derefs to `&PyAny`.

Fixes #2694
  • Loading branch information
birkenfeld committed Oct 18, 2022
1 parent bec726c commit a001311
Show file tree
Hide file tree
Showing 6 changed files with 10 additions and 10 deletions.
2 changes: 0 additions & 2 deletions guide/src/ecosystem/async-await.md
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,6 @@ fn main() -> PyResult<()> {
uvloop
.as_ref(py)
.getattr("Loop")?
.downcast::<PyType>()
.unwrap()
)?);
Ok(())
})?;
Expand Down
3 changes: 3 additions & 0 deletions newsfragments/2695.changed.md
Original file line number Diff line number Diff line change
@@ -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__`.
3 changes: 1 addition & 2 deletions src/conversions/path.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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)?
Expand Down
4 changes: 2 additions & 2 deletions src/err/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
6 changes: 3 additions & 3 deletions src/types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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());
Expand All @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion src/types/typeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit a001311

Please sign in to comment.