Skip to content

Commit 1d2bc30

Browse files
Add utc fast paths
1 parent 68217d8 commit 1d2bc30

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

src/conversions/jiff.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ use crate::sync::GILOnceCell;
66
#[cfg(not(Py_LIMITED_API))]
77
use crate::types::datetime::timezone_from_offset;
88
#[cfg(Py_LIMITED_API)]
9-
use crate::types::datetime_abi::{check_type, DatetimeTypes};
9+
use crate::types::datetime_abi::{check_type, timezone_utc, DatetimeTypes};
1010
#[cfg(Py_LIMITED_API)]
1111
use crate::types::IntoPyDict;
12-
use crate::types::{PyAnyMethods, PyNone, PyType};
1312
#[cfg(not(Py_LIMITED_API))]
1413
use crate::types::{
15-
PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess, PyTzInfo,
16-
PyTzInfoAccess,
14+
timezone_utc, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess,
15+
PyTzInfo, PyTzInfoAccess,
1716
};
17+
use crate::types::{PyAnyMethods, PyNone, PyType};
1818
use crate::{intern, Bound, FromPyObject, IntoPyObject, Py, PyAny, PyErr, PyResult, Python};
1919
use jiff::civil::{Date, DateTime, Time};
2020
use jiff::tz::{AmbiguousOffset, Offset, TimeZone};
@@ -410,7 +410,9 @@ impl<'py> IntoPyObject<'py> for &TimeZone {
410410
type Error = PyErr;
411411

412412
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
413-
if let Some(iana_name) = self.iana_name() {
413+
if self == &TimeZone::UTC {
414+
Ok(timezone_utc(py))
415+
} else if let Some(iana_name) = self.iana_name() {
414416
static ZONE_INFO: GILOnceCell<Py<PyType>> = GILOnceCell::new();
415417
let tz = ZONE_INFO
416418
.import(py, "zoneinfo", "ZoneInfo")
@@ -433,6 +435,12 @@ impl<'py> IntoPyObject<'py> for &TimeZone {
433435

434436
impl<'py> FromPyObject<'py> for TimeZone {
435437
fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
438+
#[cfg(not(Py_LIMITED_API))]
439+
let ob = ob.downcast::<PyTzInfo>()?;
440+
441+
#[cfg(Py_LIMITED_API)]
442+
check_type(ob, &DatetimeTypes::get(ob.py()).tzinfo, "PyTzInfo")?;
443+
436444
let attr = intern!(ob.py(), "key");
437445
if ob.hasattr(attr)? {
438446
Ok(TimeZone::get(&ob.getattr(attr)?.extract::<PyBackedStr>()?)?)
@@ -451,6 +459,10 @@ impl<'py> IntoPyObject<'py> for &Offset {
451459
type Error = PyErr;
452460

453461
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
462+
if self == &Offset::UTC {
463+
return Ok(timezone_utc(py));
464+
}
465+
454466
let delta = self.duration_since(Offset::UTC).into_pyobject(py)?;
455467

456468
#[cfg(not(Py_LIMITED_API))]
@@ -587,6 +599,7 @@ impl<'py> IntoPyObject<'py> for Span {
587599
type Error = PyErr;
588600

589601
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
602+
// This can fail if this Span contains units greater than days.
590603
let duration: SignedDuration = self.try_into()?;
591604
duration.into_pyobject(py)
592605
}

0 commit comments

Comments
 (0)