1 | use crate::{ffi, PyAny, PyDowncastError, PyTryFrom, Python}; |
2 | |
3 | /// Represents the Python `NotImplemented` object. |
4 | #[repr (transparent)] |
5 | pub struct PyNotImplemented(PyAny); |
6 | |
7 | pyobject_native_type_named!(PyNotImplemented); |
8 | pyobject_native_type_extract!(PyNotImplemented); |
9 | |
10 | impl PyNotImplemented { |
11 | /// Returns the `NotImplemented` object. |
12 | #[inline ] |
13 | pub fn get(py: Python<'_>) -> &PyNotImplemented { |
14 | unsafe { py.from_borrowed_ptr(ffi::Py_NotImplemented()) } |
15 | } |
16 | } |
17 | |
18 | impl<'v> PyTryFrom<'v> for PyNotImplemented { |
19 | fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, crate::PyDowncastError<'v>> { |
20 | let value: &PyAny = value.into(); |
21 | if unsafe { ffi::Py_NotImplemented() == value.as_ptr() } { |
22 | return unsafe { Ok(value.downcast_unchecked()) }; |
23 | } |
24 | Err(PyDowncastError::new(from:value, to:"NotImplementedType" )) |
25 | } |
26 | |
27 | fn try_from_exact<V: Into<&'v PyAny>>( |
28 | value: V, |
29 | ) -> Result<&'v Self, crate::PyDowncastError<'v>> { |
30 | value.into().downcast() |
31 | } |
32 | |
33 | unsafe fn try_from_unchecked<V: Into<&'v PyAny>>(value: V) -> &'v Self { |
34 | let ptr: *const PyNotImplemented = value.into() as *const _ as *const PyNotImplemented; |
35 | &*ptr |
36 | } |
37 | } |
38 | |
39 | #[cfg (test)] |
40 | mod tests { |
41 | use crate::types::{PyDict, PyNotImplemented}; |
42 | use crate::Python; |
43 | |
44 | #[test ] |
45 | fn test_notimplemented_is_itself() { |
46 | Python::with_gil(|py| { |
47 | assert!(PyNotImplemented::get(py) |
48 | .downcast::<PyNotImplemented>() |
49 | .unwrap() |
50 | .is(&py.NotImplemented())); |
51 | }) |
52 | } |
53 | |
54 | #[test ] |
55 | fn test_dict_is_not_notimplemented() { |
56 | Python::with_gil(|py| { |
57 | assert!(PyDict::new(py).downcast::<PyNotImplemented>().is_err()); |
58 | }) |
59 | } |
60 | } |
61 | |