1use crate::sync::GILOnceCell;
2use crate::types::PyAnyMethods;
3use crate::{Bound, DowncastError, PyAny, PyErr, PyObject, PyResult, Python};
4
5pub(crate) struct DatetimeTypes {
6 pub(crate) date: PyObject,
7 pub(crate) datetime: PyObject,
8 pub(crate) time: PyObject,
9 pub(crate) timedelta: PyObject,
10 pub(crate) timezone: PyObject,
11 pub(crate) timezone_utc: PyObject,
12 pub(crate) tzinfo: PyObject,
13}
14
15impl DatetimeTypes {
16 pub(crate) fn get(py: Python<'_>) -> &Self {
17 Self::try_get(py).expect(msg:"failed to load datetime module")
18 }
19
20 pub(crate) fn try_get(py: Python<'_>) -> PyResult<&Self> {
21 static TYPES: GILOnceCell<DatetimeTypes> = GILOnceCell::new();
22 TYPES.get_or_try_init(py, || {
23 let datetime: Bound<'_, PyModule> = py.import(name:"datetime")?;
24 let timezone: Bound<'_, PyAny> = datetime.getattr(attr_name:"timezone")?;
25 Ok::<_, PyErr>(Self {
26 date: datetime.getattr(attr_name:"date")?.into(),
27 datetime: datetime.getattr(attr_name:"datetime")?.into(),
28 time: datetime.getattr(attr_name:"time")?.into(),
29 timedelta: datetime.getattr(attr_name:"timedelta")?.into(),
30 timezone_utc: timezone.getattr(attr_name:"utc")?.into(),
31 timezone: timezone.into(),
32 tzinfo: datetime.getattr(attr_name:"tzinfo")?.into(),
33 })
34 })
35 }
36}
37
38pub(crate) fn timezone_utc(py: Python<'_>) -> Bound<'_, PyAny> {
39 DatetimeTypes::get(py).timezone_utc.bind(py).clone()
40}
41
42pub(crate) fn check_type(
43 value: &Bound<'_, PyAny>,
44 t: &PyObject,
45 type_name: &'static str,
46) -> PyResult<()> {
47 if !value.is_instance(ty:t.bind(value.py()))? {
48 return Err(DowncastError::new(from:value, to:type_name).into());
49 }
50 Ok(())
51}
52