Skip to content

Commit

Permalink
Chrono: makes FromPyObject impl on DateTime generic
Browse files Browse the repository at this point in the history
ToPyObject was already generic
  • Loading branch information
Tpt committed Dec 18, 2023
1 parent ff50285 commit fabd043
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 20 deletions.
1 change: 1 addition & 0 deletions newsfragments/3663.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implements `FromPyObject` on `chrono::DateTime<Tz>` for all `Tz` and not only `FixedOffset` and `Utc`
30 changes: 10 additions & 20 deletions src/conversions/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,34 +200,24 @@ impl<Tz: TimeZone> IntoPy<PyObject> for DateTime<Tz> {
}
}

impl FromPyObject<'_> for DateTime<FixedOffset> {
fn extract(ob: &PyAny) -> PyResult<DateTime<FixedOffset>> {
impl<Tz: TimeZone + for<'a> FromPyObject<'a>> FromPyObject<'_> for DateTime<Tz> {
fn extract(ob: &PyAny) -> PyResult<DateTime<Tz>> {
let dt: &PyDateTime = ob.downcast()?;
let tz: FixedOffset = if let Some(tzinfo) = dt.get_tzinfo() {
let tz = if let Some(tzinfo) = dt.get_tzinfo() {
tzinfo.extract()?
} else {
return Err(PyTypeError::new_err(
"expected a datetime with non-None tzinfo",
));
};
let dt = NaiveDateTime::new(py_date_to_naive_date(dt)?, py_time_to_naive_time(dt)?);
// `FixedOffset` cannot have ambiguities so we don't have to worry about DST folds and such
Ok(dt.and_local_timezone(tz).unwrap())
}
}

impl FromPyObject<'_> for DateTime<Utc> {
fn extract(ob: &PyAny) -> PyResult<DateTime<Utc>> {
let dt: &PyDateTime = ob.downcast()?;
let _: Utc = if let Some(tzinfo) = dt.get_tzinfo() {
tzinfo.extract()?
} else {
return Err(PyTypeError::new_err(
"expected a datetime with non-None tzinfo",
));
};
let dt = NaiveDateTime::new(py_date_to_naive_date(dt)?, py_time_to_naive_time(dt)?);
Ok(dt.and_utc())
dt.and_local_timezone(tz).single().ok_or_else(|| {
PyValueError::new_err(format!(
"The datetime {} contains an incompatible or ambiguous timezone",
ob.repr()
.unwrap_or_else(|_| PyUnicode::new(ob.py(), "repr failed"))
))
})
}
}

Expand Down

0 comments on commit fabd043

Please sign in to comment.