pyo3/types/
notimplemented.rs1use crate::{
2 ffi, ffi_ptr_ext::FfiPtrExt, types::any::PyAnyMethods, Borrowed, Bound, PyAny, PyTypeInfo,
3 Python,
4};
5
6#[repr(transparent)]
11pub struct PyNotImplemented(PyAny);
12
13pyobject_native_type_named!(PyNotImplemented);
14
15impl PyNotImplemented {
16 #[inline]
18 pub fn get(py: Python<'_>) -> Borrowed<'_, '_, PyNotImplemented> {
19 unsafe {
20 ffi::Py_NotImplemented()
21 .assume_borrowed(py)
22 .downcast_unchecked()
23 }
24 }
25
26 #[deprecated(since = "0.23.0", note = "renamed to `PyNotImplemented::get`")]
28 #[inline]
29 pub fn get_bound(py: Python<'_>) -> Borrowed<'_, '_, PyNotImplemented> {
30 Self::get(py)
31 }
32}
33
34unsafe impl PyTypeInfo for PyNotImplemented {
35 const NAME: &'static str = "NotImplementedType";
36 const MODULE: Option<&'static str> = None;
37
38 fn type_object_raw(_py: Python<'_>) -> *mut ffi::PyTypeObject {
39 unsafe { ffi::Py_TYPE(ffi::Py_NotImplemented()) }
40 }
41
42 #[inline]
43 fn is_type_of(object: &Bound<'_, PyAny>) -> bool {
44 Self::is_exact_type_of(object)
46 }
47
48 #[inline]
49 fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool {
50 object.is(&**Self::get(object.py()))
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use crate::types::any::PyAnyMethods;
57 use crate::types::{PyDict, PyNotImplemented};
58 use crate::{PyTypeInfo, Python};
59
60 #[test]
61 fn test_notimplemented_is_itself() {
62 Python::with_gil(|py| {
63 assert!(PyNotImplemented::get(py).is_instance_of::<PyNotImplemented>());
64 assert!(PyNotImplemented::get(py).is_exact_instance_of::<PyNotImplemented>());
65 })
66 }
67
68 #[test]
69 fn test_notimplemented_type_object_consistent() {
70 Python::with_gil(|py| {
71 assert!(PyNotImplemented::get(py)
72 .get_type()
73 .is(&PyNotImplemented::type_object(py)));
74 })
75 }
76
77 #[test]
78 fn test_dict_is_not_notimplemented() {
79 Python::with_gil(|py| {
80 assert!(PyDict::new(py).downcast::<PyNotImplemented>().is_err());
81 })
82 }
83}