Skip to content

Commit

Permalink
Merge #3161
Browse files Browse the repository at this point in the history
3161: add PyAny::is_exact_instance and PyAny::is_exact_instance_of r=adamreichold a=davidhewitt

Split off from #2881. I'll rebase after that merges.

Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
  • Loading branch information
bors[bot] and davidhewitt authored May 21, 2023
2 parents cc6f9d7 + 82a879f commit a3c4fd2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
1 change: 1 addition & 0 deletions newsfragments/3161.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `PyAny::is_exact_instance` and `PyAny::is_exact_instance_of`.
49 changes: 46 additions & 3 deletions src/types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,14 @@ impl PyAny {
Ok(result == 1)
}

/// Checks whether this object is an instance of exactly type `ty` (not a subclass).
///
/// This is equivalent to the Python expression `type(self) is ty`.
#[inline]
pub fn is_exact_instance(&self, ty: &PyAny) -> bool {
self.get_type().is(ty)
}

/// Checks whether this object is an instance of type `T`.
///
/// This is equivalent to the Python expression `isinstance(self, T)`,
Expand All @@ -921,6 +929,15 @@ impl PyAny {
T::is_type_of(self)
}

/// Checks whether this object is an instance of exactly type `T`.
///
/// This is equivalent to the Python expression `type(self) is T`,
/// if the type `T` is known at compile time.
#[inline]
pub fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool {
T::is_exact_type_of(self)
}

/// Determines if self contains `value`.
///
/// This is equivalent to the Python expression `value in self`.
Expand Down Expand Up @@ -957,7 +974,7 @@ impl PyAny {
#[cfg(test)]
mod tests {
use crate::{
types::{IntoPyDict, PyList, PyLong, PyModule},
types::{IntoPyDict, PyBool, PyList, PyLong, PyModule},
Python, ToPyObject,
};
#[test]
Expand Down Expand Up @@ -1043,7 +1060,7 @@ class SimpleClass:
}

#[test]
fn test_any_isinstance_of() {
fn test_any_is_instance_of() {
Python::with_gil(|py| {
let x = 5.to_object(py).into_ref(py);
assert!(x.is_instance_of::<PyLong>());
Expand All @@ -1054,13 +1071,39 @@ class SimpleClass:
}

#[test]
fn test_any_isinstance() {
fn test_any_is_instance() {
Python::with_gil(|py| {
let l = vec![1u8, 2].to_object(py).into_ref(py);
assert!(l.is_instance(py.get_type::<PyList>()).unwrap());
});
}

#[test]
fn test_any_is_exact_instance_of() {
Python::with_gil(|py| {
let x = 5.to_object(py).into_ref(py);
assert!(x.is_exact_instance_of::<PyLong>());

let t = PyBool::new(py, true);
assert!(t.is_instance_of::<PyLong>());
assert!(!t.is_exact_instance_of::<PyLong>());
assert!(t.is_exact_instance_of::<PyBool>());

let l = vec![x, x].to_object(py).into_ref(py);
assert!(l.is_exact_instance_of::<PyList>());
});
}

#[test]
fn test_any_is_exact_instance() {
Python::with_gil(|py| {
let t = PyBool::new(py, true);
assert!(t.is_instance(py.get_type::<PyLong>()).unwrap());
assert!(!t.is_exact_instance(py.get_type::<PyLong>()));
assert!(t.is_exact_instance(py.get_type::<PyBool>()));
});
}

#[test]
fn test_any_contains() {
Python::with_gil(|py| {
Expand Down

0 comments on commit a3c4fd2

Please sign in to comment.