From f5b18468bc6a25980169823bf285a84e860a294b Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Sun, 24 Dec 2023 15:05:51 +0000 Subject: [PATCH] partially revert changes to `PyTzInfoAccess` trait --- newsfragments/3679.changed.md | 2 +- pytests/src/datetime.rs | 4 ++-- src/conversions/chrono.rs | 4 ++-- src/types/datetime.rs | 24 +++++++++++++++++------- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/newsfragments/3679.changed.md b/newsfragments/3679.changed.md index 2e8e28a9..ab46598a 100644 --- a/newsfragments/3679.changed.md +++ b/newsfragments/3679.changed.md @@ -1 +1 @@ -Add lifetime parameter to `PyTzInfoAccess` trait and change the return type of `PyTzInfoAccess::get_tzinfo` to `Option>`. For the deprecated gil-ref API, the trait is now implemented for `&'py PyTime` and `&'py PyDateTime` instead of `PyTime` and `PyDate`. +Add lifetime parameter to `PyTzInfoAccess` trait. For the deprecated gil-ref API, the trait is now implemented for `&'py PyTime` and `&'py PyDateTime` instead of `PyTime` and `PyDate`. diff --git a/pytests/src/datetime.rs b/pytests/src/datetime.rs index 7f0492da..f5a15b4f 100644 --- a/pytests/src/datetime.rs +++ b/pytests/src/datetime.rs @@ -161,12 +161,12 @@ fn datetime_from_timestamp<'p>( #[pyfunction] fn get_datetime_tzinfo(dt: &PyDateTime) -> Option> { - dt.get_tzinfo() + dt.get_tzinfo_bound() } #[pyfunction] fn get_time_tzinfo(dt: &PyTime) -> Option> { - dt.get_tzinfo() + dt.get_tzinfo_bound() } #[pyclass(extends=PyTzInfo)] diff --git a/src/conversions/chrono.rs b/src/conversions/chrono.rs index 0ad5b445..dd541bff 100644 --- a/src/conversions/chrono.rs +++ b/src/conversions/chrono.rs @@ -248,7 +248,7 @@ impl FromPyObject<'_> for NaiveDateTime { // we return a hard error. We could silently remove tzinfo, or assume local timezone // and do a conversion, but better leave this decision to the user of the library. #[cfg(not(Py_LIMITED_API))] - let has_tzinfo = dt.get_tzinfo().is_some(); + let has_tzinfo = dt.get_tzinfo_bound().is_some(); #[cfg(Py_LIMITED_API)] let has_tzinfo = !dt.getattr(intern!(dt.py(), "tzinfo"))?.is_none(); if has_tzinfo { @@ -284,7 +284,7 @@ impl FromPyObject<'a>> FromPyObject<'_> for DateTime check_type(dt, &DatetimeTypes::get(dt.py()).datetime, "PyDateTime")?; #[cfg(not(Py_LIMITED_API))] - let tzinfo = dt.get_tzinfo(); + let tzinfo = dt.get_tzinfo_bound(); #[cfg(Py_LIMITED_API)] let tzinfo: Option<&PyAny> = dt.getattr(intern!(dt.py(), "tzinfo"))?.extract()?; diff --git a/src/types/datetime.rs b/src/types/datetime.rs index 94802fe1..b2d0f6ef 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -163,12 +163,21 @@ pub trait PyTimeAccess { /// Trait for accessing the components of a struct containing a tzinfo. pub trait PyTzInfoAccess<'py> { + /// Deprecated form of `get_tzinfo_bound`. + #[deprecated( + since = "0.21.0", + note = "`get_tzinfo` will be replaced by `get_tzinfo_bound` in a future PyO3 version" + )] + fn get_tzinfo(&self) -> Option<&'py PyTzInfo> { + self.get_tzinfo_bound().map(Bound::into_gil_ref) + } + /// Returns the tzinfo (which may be None). /// /// Implementations should conform to the upstream documentation: /// /// - fn get_tzinfo(&self) -> Option>; + fn get_tzinfo_bound(&self) -> Option>; } /// Bindings around `datetime.date` @@ -413,13 +422,13 @@ impl PyTimeAccess for Bound<'_, PyDateTime> { } impl<'py> PyTzInfoAccess<'py> for &'py PyDateTime { - fn get_tzinfo(&self) -> Option> { - Bound::borrowed_from_gil_ref(self).get_tzinfo() + fn get_tzinfo_bound(&self) -> Option> { + Bound::borrowed_from_gil_ref(self).get_tzinfo_bound() } } impl<'py> PyTzInfoAccess<'py> for Bound<'py, PyDateTime> { - fn get_tzinfo(&self) -> Option> { + fn get_tzinfo_bound(&self) -> Option> { let ptr = self.as_ptr() as *mut ffi::PyDateTime_DateTime; unsafe { if (*ptr).hastzinfo != 0 { @@ -543,13 +552,13 @@ impl PyTimeAccess for Bound<'_, PyTime> { } impl<'py> PyTzInfoAccess<'py> for &'py PyTime { - fn get_tzinfo(&self) -> Option> { - Bound::borrowed_from_gil_ref(self).get_tzinfo() + fn get_tzinfo_bound(&self) -> Option> { + Bound::borrowed_from_gil_ref(self).get_tzinfo_bound() } } impl<'py> PyTzInfoAccess<'py> for Bound<'py, PyTime> { - fn get_tzinfo(&self) -> Option> { + fn get_tzinfo_bound(&self) -> Option> { let ptr = self.as_ptr() as *mut ffi::PyDateTime_Time; unsafe { if (*ptr).hastzinfo != 0 { @@ -725,6 +734,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons + #[allow(deprecated)] fn test_get_tzinfo() { crate::Python::with_gil(|py| { let utc = timezone_utc(py);