Duration: drops truncation warning

This commit is contained in:
Tpt 2023-12-19 20:55:53 +01:00 committed by Adam Reichold
parent 8b614745cf
commit 0752942c3f
1 changed files with 16 additions and 44 deletions

View File

@ -1,4 +1,4 @@
use crate::exceptions::{PyUserWarning, PyValueError}; use crate::exceptions::PyValueError;
#[cfg(Py_LIMITED_API)] #[cfg(Py_LIMITED_API)]
use crate::sync::GILOnceCell; use crate::sync::GILOnceCell;
#[cfg(Py_LIMITED_API)] #[cfg(Py_LIMITED_API)]
@ -7,7 +7,7 @@ use crate::types::PyType;
use crate::types::{PyDelta, PyDeltaAccess}; use crate::types::{PyDelta, PyDeltaAccess};
#[cfg(Py_LIMITED_API)] #[cfg(Py_LIMITED_API)]
use crate::{intern, Py}; 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; use std::time::Duration;
const SECONDS_PER_DAY: u64 = 24 * 60 * 60; const SECONDS_PER_DAY: u64 = 24 * 60 * 60;
@ -56,30 +56,28 @@ impl ToPyObject for Duration {
let microseconds = self.subsec_micros(); let microseconds = self.subsec_micros();
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
let delta = PyDelta::new( {
py, PyDelta::new(
days.try_into() py,
.expect("Too large Rust duration for timedelta"), days.try_into()
seconds.try_into().unwrap(), .expect("Too large Rust duration for timedelta"),
microseconds.try_into().unwrap(), seconds.try_into().unwrap(),
false, microseconds.try_into().unwrap(),
) false,
.expect("failed to construct timedelta (overflow?)"); )
.expect("failed to construct timedelta (overflow?)")
.into()
}
#[cfg(Py_LIMITED_API)] #[cfg(Py_LIMITED_API)]
let delta = { {
static TIMEDELTA: GILOnceCell<Py<PyType>> = GILOnceCell::new(); static TIMEDELTA: GILOnceCell<Py<PyType>> = GILOnceCell::new();
TIMEDELTA TIMEDELTA
.get_or_try_init_type_ref(py, "datetime", "timedelta") .get_or_try_init_type_ref(py, "datetime", "timedelta")
.unwrap() .unwrap()
.call1((days, seconds, microseconds)) .call1((days, seconds, microseconds))
.unwrap() .unwrap()
}; .into()
if self.subsec_nanos() % 1_000 != 0 {
warn_truncated_nanoseconds(delta);
} }
delta.into()
} }
} }
@ -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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -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 { fn new_timedelta(py: Python<'_>, days: i32, seconds: i32, microseconds: i32) -> &PyAny {
timedelta_class(py) timedelta_class(py)
.call1((days, seconds, microseconds)) .call1((days, seconds, microseconds))