pyo3_stub_gen/stub_type/
pyo3.rs

1use crate::runtime::PyRuntimeType;
2use crate::stub_type::*;
3use ::pyo3::{
4    basic::CompareOp,
5    pybacked::{PyBackedBytes, PyBackedStr},
6    pyclass::boolean_struct::False,
7    types::*,
8    Bound, Py, PyClass, PyClassInitializer, PyRef, PyRefMut, PyResult, Python,
9};
10use maplit::hashset;
11use std::collections::HashMap;
12
13impl PyStubType for PyAny {
14    fn type_output() -> TypeInfo {
15        TypeInfo {
16            name: "typing.Any".to_string(),
17            source_module: None,
18            import: hashset! { "typing".into() },
19            type_refs: HashMap::new(),
20        }
21    }
22}
23impl PyRuntimeType for PyAny {
24    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
25        // PyAny maps to `object` at runtime
26        Ok(py.get_type::<::pyo3::types::PyAny>().into_any())
27    }
28}
29
30impl<T: PyStubType> PyStubType for Py<T> {
31    fn type_input() -> TypeInfo {
32        T::type_input()
33    }
34    fn type_output() -> TypeInfo {
35        T::type_output()
36    }
37}
38impl<T: PyRuntimeType> PyRuntimeType for Py<T> {
39    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
40        T::runtime_type_object(py)
41    }
42}
43
44impl<T: PyStubType + PyClass> PyStubType for PyRef<'_, T> {
45    fn type_input() -> TypeInfo {
46        T::type_input()
47    }
48    fn type_output() -> TypeInfo {
49        T::type_output()
50    }
51}
52impl<T: PyRuntimeType + PyClass> PyRuntimeType for PyRef<'_, T> {
53    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
54        T::runtime_type_object(py)
55    }
56}
57
58impl<T: PyStubType + PyClass<Frozen = False>> PyStubType for PyRefMut<'_, T> {
59    fn type_input() -> TypeInfo {
60        T::type_input()
61    }
62    fn type_output() -> TypeInfo {
63        T::type_output()
64    }
65}
66impl<T: PyRuntimeType + PyClass<Frozen = False>> PyRuntimeType for PyRefMut<'_, T> {
67    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
68        T::runtime_type_object(py)
69    }
70}
71
72impl<T: PyStubType> PyStubType for Bound<'_, T> {
73    fn type_input() -> TypeInfo {
74        T::type_input()
75    }
76    fn type_output() -> TypeInfo {
77        T::type_output()
78    }
79}
80impl<T: PyRuntimeType> PyRuntimeType for Bound<'_, T> {
81    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
82        T::runtime_type_object(py)
83    }
84}
85
86impl<T: PyClass + PyStubType> PyStubType for PyClassInitializer<T> {
87    fn type_output() -> TypeInfo {
88        T::type_output()
89    }
90    fn type_input() -> TypeInfo {
91        T::type_input()
92    }
93}
94impl<T: PyClass + PyRuntimeType> PyRuntimeType for PyClassInitializer<T> {
95    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
96        T::runtime_type_object(py)
97    }
98}
99
100macro_rules! impl_builtin {
101    ($ty:ty, $pytype:expr) => {
102        impl PyStubType for $ty {
103            fn type_output() -> TypeInfo {
104                TypeInfo {
105                    name: $pytype.to_string(),
106                    source_module: None,
107                    import: HashSet::new(),
108                    type_refs: HashMap::new(),
109                }
110            }
111        }
112        impl PyRuntimeType for $ty {
113            fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
114                Ok(py.get_type::<$ty>().into_any())
115            }
116        }
117    };
118}
119
120impl_builtin!(PyBool, "bool");
121impl_builtin!(PyInt, "int");
122impl_builtin!(PyFloat, "float");
123impl_builtin!(PyComplex, "complex");
124impl_builtin!(PyList, "list");
125impl_builtin!(PyTuple, "tuple");
126impl_builtin!(PySlice, "slice");
127impl_builtin!(PyDict, "dict");
128impl_builtin!(PySet, "set");
129impl_builtin!(PyString, "str");
130impl_builtin!(PyByteArray, "bytearray");
131impl_builtin!(PyBytes, "bytes");
132impl_builtin!(PyType, "type");
133
134// PyBackedStr and PyBackedBytes don't have PyTypeInfo, use underlying types
135impl PyStubType for PyBackedStr {
136    fn type_output() -> TypeInfo {
137        TypeInfo {
138            name: "str".to_string(),
139            source_module: None,
140            import: HashSet::new(),
141            type_refs: HashMap::new(),
142        }
143    }
144}
145impl PyRuntimeType for PyBackedStr {
146    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
147        Ok(py.get_type::<PyString>().into_any())
148    }
149}
150
151impl PyStubType for PyBackedBytes {
152    fn type_output() -> TypeInfo {
153        TypeInfo {
154            name: "bytes".to_string(),
155            source_module: None,
156            import: HashSet::new(),
157            type_refs: HashMap::new(),
158        }
159    }
160}
161impl PyRuntimeType for PyBackedBytes {
162    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
163        Ok(py.get_type::<PyBytes>().into_any())
164    }
165}
166
167// CompareOp maps to int at stub level but is not a Python type
168impl PyStubType for CompareOp {
169    fn type_output() -> TypeInfo {
170        TypeInfo {
171            name: "int".to_string(),
172            source_module: None,
173            import: HashSet::new(),
174            type_refs: HashMap::new(),
175        }
176    }
177}
178impl PyRuntimeType for CompareOp {
179    fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
180        Ok(py.get_type::<PyInt>().into_any())
181    }
182}
183
184macro_rules! impl_simple {
185    ($ty:ty, $mod:expr, $pytype:expr) => {
186        impl PyStubType for $ty {
187            fn type_output() -> TypeInfo {
188                TypeInfo {
189                    name: concat!($mod, ".", $pytype).to_string(),
190                    source_module: None,
191                    import: hashset! { $mod.into() },
192                    type_refs: HashMap::new(),
193                }
194            }
195        }
196        impl PyRuntimeType for $ty {
197            fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, ::pyo3::PyAny>> {
198                Ok(py.get_type::<$ty>().into_any())
199            }
200        }
201    };
202}
203
204impl_simple!(PyDate, "datetime", "date");
205impl_simple!(PyDateTime, "datetime", "datetime");
206impl_simple!(PyDelta, "datetime", "timedelta");
207impl_simple!(PyTime, "datetime", "time");
208impl_simple!(PyTzInfo, "datetime", "tzinfo");