Skip to content

Commit

Permalink
Duration: drops truncation warning
Browse files Browse the repository at this point in the history
  • Loading branch information
Tpt committed Dec 19, 2023
1 parent b142797 commit 33875e8
Showing 1 changed file with 16 additions and 44 deletions.
60 changes: 16 additions & 44 deletions src/conversions/std/duration.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::exceptions::{PyUserWarning, PyValueError};
use crate::exceptions::PyValueError;
#[cfg(Py_LIMITED_API)]
use crate::sync::GILOnceCell;
#[cfg(Py_LIMITED_API)]
Expand All @@ -7,7 +7,7 @@ use crate::types::PyType;
use crate::types::{PyDelta, PyDeltaAccess};
#[cfg(Py_LIMITED_API)]
use crate::{intern, Py};
use crate::{FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject};
use crate::{FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
use std::time::Duration;

const SECONDS_PER_DAY: u64 = 24 * 60 * 60;
Expand Down Expand Up @@ -56,30 +56,28 @@ impl ToPyObject for Duration {
let microseconds = self.subsec_micros();

#[cfg(not(Py_LIMITED_API))]
let delta = PyDelta::new(
py,
days.try_into()
.expect("Too large Rust duration for timedelta"),
seconds.try_into().unwrap(),
microseconds.try_into().unwrap(),
false,
)
.expect("failed to construct timedelta (overflow?)");
{
PyDelta::new(
py,
days.try_into()
.expect("Too large Rust duration for timedelta"),
seconds.try_into().unwrap(),
microseconds.try_into().unwrap(),
false,
)
.expect("failed to construct timedelta (overflow?)")
.into()
}
#[cfg(Py_LIMITED_API)]
let delta = {
{
static TIMEDELTA: GILOnceCell<Py<PyType>> = GILOnceCell::new();
TIMEDELTA
.get_or_try_init_type_ref(py, "datetime", "timedelta")
.unwrap()
.call1((days, seconds, microseconds))
.unwrap()
};

if self.subsec_nanos() % 1_000 != 0 {
warn_truncated_nanoseconds(delta);
.into()
}

delta.into()
}
}

Expand All @@ -89,18 +87,6 @@ impl IntoPy<PyObject> for Duration {
}
}

fn warn_truncated_nanoseconds(obj: &PyAny) {
let py = obj.py();
if let Err(e) = PyErr::warn(
py,
py.get_type::<PyUserWarning>(),
"ignored nanoseconds, `datetime.timedelta` does not support nanoseconds",
0,
) {
e.write_unraisable(py, Some(obj))
};
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -198,20 +184,6 @@ mod tests {
})
}

#[test]
fn test_topyobject_precision_loss() {
Python::with_gil(|py| {
assert_warnings!(
py,
Duration::new(0, 1).to_object(py),
[(
PyUserWarning,
"ignored nanoseconds, `datetime.timedelta` does not support nanoseconds"
)]
);
})
}

fn new_timedelta(py: Python<'_>, days: i32, seconds: i32, microseconds: i32) -> &PyAny {
timedelta_class(py)
.call1((days, seconds, microseconds))
Expand Down

0 comments on commit 33875e8

Please sign in to comment.