1use crate::runtime::PyRuntimeType;
4use crate::stub_type::*;
5use ::pyo3::prelude::*;
6use ::pyo3::types::{PyBool, PyComplex, PyFloat, PyInt, PyString};
7use std::{
8 borrow::Cow,
9 ffi::{OsStr, OsString},
10 path::PathBuf,
11 rc::Rc,
12 sync::Arc,
13 time::SystemTime,
14};
15
16macro_rules! impl_builtin {
17 ($ty:ty, $pytype:expr, $py_type_obj:ty) => {
18 impl PyStubType for $ty {
19 fn type_output() -> TypeInfo {
20 TypeInfo::builtin($pytype)
21 }
22 }
23 impl PyRuntimeType for $ty {
24 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
25 Ok(py.get_type::<$py_type_obj>().into_any())
26 }
27 }
28 };
29}
30
31macro_rules! impl_with_module {
32 ($ty:ty, $pytype:expr, $module:expr) => {
33 impl PyStubType for $ty {
34 fn type_output() -> TypeInfo {
35 TypeInfo::with_module($pytype, $module.into())
36 }
37 }
38 impl PyRuntimeType for $ty {
39 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
40 let module = py.import($module)?;
42 let type_name = $pytype.rsplit('.').next().unwrap_or($pytype);
44 module.getattr(type_name)
45 }
46 }
47 };
48}
49
50impl PyStubType for () {
52 fn type_output() -> TypeInfo {
53 TypeInfo::none()
54 }
55}
56impl PyRuntimeType for () {
57 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
58 Ok(py.get_type::<::pyo3::types::PyNone>().into_any())
60 }
61}
62
63impl_builtin!(bool, "bool", PyBool);
64impl_builtin!(u8, "int", PyInt);
65impl_builtin!(u16, "int", PyInt);
66impl_builtin!(u32, "int", PyInt);
67impl_builtin!(u64, "int", PyInt);
68impl_builtin!(u128, "int", PyInt);
69impl_builtin!(usize, "int", PyInt);
70impl_builtin!(i8, "int", PyInt);
71impl_builtin!(i16, "int", PyInt);
72impl_builtin!(i32, "int", PyInt);
73impl_builtin!(i64, "int", PyInt);
74impl_builtin!(i128, "int", PyInt);
75impl_builtin!(isize, "int", PyInt);
76impl_builtin!(f32, "float", PyFloat);
77impl_builtin!(f64, "float", PyFloat);
78impl_builtin!(num_complex::Complex32, "complex", PyComplex);
79impl_builtin!(num_complex::Complex64, "complex", PyComplex);
80
81impl_builtin!(char, "str", PyString);
82impl_builtin!(&str, "str", PyString);
83impl_builtin!(OsStr, "str", PyString);
84impl_builtin!(String, "str", PyString);
85impl_builtin!(OsString, "str", PyString);
86impl_builtin!(Cow<'_, str>, "str", PyString);
87impl_builtin!(Cow<'_, OsStr>, "str", PyString);
88impl_builtin!(Cow<'_, [u8]>, "bytes", ::pyo3::types::PyBytes);
89
90#[cfg(feature = "ordered-float")]
91mod impl_ordered_float {
92 use super::*;
93 use ::pyo3::types::PyFloat;
94 impl_builtin!(ordered_float::NotNan<f32>, "float", PyFloat);
95 impl_builtin!(ordered_float::NotNan<f64>, "float", PyFloat);
96 impl_builtin!(ordered_float::OrderedFloat<f32>, "float", PyFloat);
97 impl_builtin!(ordered_float::OrderedFloat<f64>, "float", PyFloat);
98}
99
100impl PyStubType for PathBuf {
101 fn type_output() -> TypeInfo {
102 TypeInfo::with_module("pathlib.Path", "pathlib".into())
103 }
104 fn type_input() -> TypeInfo {
105 TypeInfo::builtin("str")
106 | TypeInfo::with_module("os.PathLike", "os".into())
107 | TypeInfo::with_module("pathlib.Path", "pathlib".into())
108 }
109}
110impl PyRuntimeType for PathBuf {
111 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
112 let pathlib = py.import("pathlib")?;
113 pathlib.getattr("Path")
114 }
115}
116
117impl<Tz: chrono::TimeZone> PyStubType for chrono::DateTime<Tz> {
118 fn type_output() -> TypeInfo {
119 TypeInfo::with_module("datetime.datetime", "datetime".into())
120 }
121}
122impl<Tz: chrono::TimeZone> PyRuntimeType for chrono::DateTime<Tz> {
123 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
124 let datetime = py.import("datetime")?;
125 datetime.getattr("datetime")
126 }
127}
128
129impl_with_module!(SystemTime, "datetime.datetime", "datetime");
130impl_with_module!(chrono::NaiveDateTime, "datetime.datetime", "datetime");
131impl_with_module!(chrono::NaiveDate, "datetime.date", "datetime");
132impl_with_module!(chrono::NaiveTime, "datetime.time", "datetime");
133impl_with_module!(chrono::FixedOffset, "datetime.tzinfo", "datetime");
134impl_with_module!(chrono::Utc, "datetime.tzinfo", "datetime");
135impl_with_module!(std::time::Duration, "datetime.timedelta", "datetime");
136impl_with_module!(chrono::Duration, "datetime.timedelta", "datetime");
137impl_with_module!(time::Duration, "datetime.timedelta", "datetime");
138impl_with_module!(time::Date, "datetime.date", "datetime");
139impl_with_module!(time::OffsetDateTime, "datetime.datetime", "datetime");
140impl_with_module!(time::PrimitiveDateTime, "datetime.datetime", "datetime");
141impl_with_module!(time::UtcDateTime, "datetime.datetime", "datetime");
142impl_with_module!(time::Time, "datetime.time", "datetime");
143impl_with_module!(time::UtcOffset, "datetime.tzinfo", "datetime");
144
145impl<T: PyStubType> PyStubType for &T {
146 fn type_input() -> TypeInfo {
147 T::type_input()
148 }
149 fn type_output() -> TypeInfo {
150 T::type_output()
151 }
152}
153impl<T: PyRuntimeType> PyRuntimeType for &T {
154 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
155 T::runtime_type_object(py)
156 }
157}
158
159impl<T: PyStubType> PyStubType for Rc<T> {
160 fn type_input() -> TypeInfo {
161 T::type_input()
162 }
163 fn type_output() -> TypeInfo {
164 T::type_output()
165 }
166}
167impl<T: PyRuntimeType> PyRuntimeType for Rc<T> {
168 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
169 T::runtime_type_object(py)
170 }
171}
172
173impl<T: PyStubType> PyStubType for Arc<T> {
174 fn type_input() -> TypeInfo {
175 T::type_input()
176 }
177 fn type_output() -> TypeInfo {
178 T::type_output()
179 }
180}
181impl<T: PyRuntimeType> PyRuntimeType for Arc<T> {
182 fn runtime_type_object(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
183 T::runtime_type_object(py)
184 }
185}