Duration: drops truncation warning
This commit is contained in:
parent
8b614745cf
commit
0752942c3f
|
@ -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))
|
||||||
|
|
Loading…
Reference in New Issue