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