add _bound
constructors for datetime types (#3778)
* add `_bound` constructors for datetime types * review: Icxolu feedback * update uses of deprecated timezone_utc
This commit is contained in:
parent
1279467d27
commit
5b9b76fe58
|
@ -7,8 +7,8 @@ use pyo3::types::{
|
|||
};
|
||||
|
||||
#[pyfunction]
|
||||
fn make_date(py: Python<'_>, year: i32, month: u8, day: u8) -> PyResult<&PyDate> {
|
||||
PyDate::new(py, year, month, day)
|
||||
fn make_date(py: Python<'_>, year: i32, month: u8, day: u8) -> PyResult<Bound<'_, PyDate>> {
|
||||
PyDate::new_bound(py, year, month, day)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
@ -17,34 +17,34 @@ fn get_date_tuple<'p>(py: Python<'p>, d: &PyDate) -> Bound<'p, PyTuple> {
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn date_from_timestamp(py: Python<'_>, timestamp: i64) -> PyResult<&PyDate> {
|
||||
PyDate::from_timestamp(py, timestamp)
|
||||
fn date_from_timestamp(py: Python<'_>, timestamp: i64) -> PyResult<Bound<'_, PyDate>> {
|
||||
PyDate::from_timestamp_bound(py, timestamp)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn make_time<'p>(
|
||||
py: Python<'p>,
|
||||
fn make_time<'py>(
|
||||
py: Python<'py>,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
) -> PyResult<&'p PyTime> {
|
||||
PyTime::new(py, hour, minute, second, microsecond, tzinfo)
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
) -> PyResult<Bound<'py, PyTime>> {
|
||||
PyTime::new_bound(py, hour, minute, second, microsecond, tzinfo)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
#[pyo3(signature = (hour, minute, second, microsecond, tzinfo, fold))]
|
||||
fn time_with_fold<'p>(
|
||||
py: Python<'p>,
|
||||
fn time_with_fold<'py>(
|
||||
py: Python<'py>,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
fold: bool,
|
||||
) -> PyResult<&'p PyTime> {
|
||||
PyTime::new_with_fold(py, hour, minute, second, microsecond, tzinfo, fold)
|
||||
) -> PyResult<Bound<'py, PyTime>> {
|
||||
PyTime::new_bound_with_fold(py, hour, minute, second, microsecond, tzinfo, fold)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
@ -75,14 +75,19 @@ fn get_time_tuple_fold<'p>(py: Python<'p>, dt: &PyTime) -> Bound<'p, PyTuple> {
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn make_delta(py: Python<'_>, days: i32, seconds: i32, microseconds: i32) -> PyResult<&PyDelta> {
|
||||
PyDelta::new(py, days, seconds, microseconds, true)
|
||||
fn make_delta(
|
||||
py: Python<'_>,
|
||||
days: i32,
|
||||
seconds: i32,
|
||||
microseconds: i32,
|
||||
) -> PyResult<Bound<'_, PyDelta>> {
|
||||
PyDelta::new_bound(py, days, seconds, microseconds, true)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_delta_tuple<'p>(py: Python<'p>, delta: &PyDelta) -> Bound<'p, PyTuple> {
|
||||
fn get_delta_tuple<'py>(delta: &Bound<'py, PyDelta>) -> Bound<'py, PyTuple> {
|
||||
PyTuple::new_bound(
|
||||
py,
|
||||
delta.py(),
|
||||
[
|
||||
delta.get_days(),
|
||||
delta.get_seconds(),
|
||||
|
@ -93,8 +98,8 @@ fn get_delta_tuple<'p>(py: Python<'p>, delta: &PyDelta) -> Bound<'p, PyTuple> {
|
|||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[pyfunction]
|
||||
fn make_datetime<'p>(
|
||||
py: Python<'p>,
|
||||
fn make_datetime<'py>(
|
||||
py: Python<'py>,
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
|
@ -102,9 +107,9 @@ fn make_datetime<'p>(
|
|||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
) -> PyResult<&'p PyDateTime> {
|
||||
PyDateTime::new(
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
) -> PyResult<Bound<'py, PyDateTime>> {
|
||||
PyDateTime::new_bound(
|
||||
py,
|
||||
year,
|
||||
month,
|
||||
|
@ -118,7 +123,7 @@ fn make_datetime<'p>(
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_datetime_tuple<'p>(py: Python<'p>, dt: &PyDateTime) -> Bound<'p, PyTuple> {
|
||||
fn get_datetime_tuple<'py>(py: Python<'py>, dt: &Bound<'py, PyDateTime>) -> Bound<'py, PyTuple> {
|
||||
PyTuple::new_bound(
|
||||
py,
|
||||
[
|
||||
|
@ -134,7 +139,10 @@ fn get_datetime_tuple<'p>(py: Python<'p>, dt: &PyDateTime) -> Bound<'p, PyTuple>
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_datetime_tuple_fold<'p>(py: Python<'p>, dt: &PyDateTime) -> Bound<'p, PyTuple> {
|
||||
fn get_datetime_tuple_fold<'py>(
|
||||
py: Python<'py>,
|
||||
dt: &Bound<'py, PyDateTime>,
|
||||
) -> Bound<'py, PyTuple> {
|
||||
PyTuple::new_bound(
|
||||
py,
|
||||
[
|
||||
|
@ -151,21 +159,21 @@ fn get_datetime_tuple_fold<'p>(py: Python<'p>, dt: &PyDateTime) -> Bound<'p, PyT
|
|||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn datetime_from_timestamp<'p>(
|
||||
py: Python<'p>,
|
||||
fn datetime_from_timestamp<'py>(
|
||||
py: Python<'py>,
|
||||
ts: f64,
|
||||
tz: Option<&PyTzInfo>,
|
||||
) -> PyResult<&'p PyDateTime> {
|
||||
PyDateTime::from_timestamp(py, ts, tz)
|
||||
tz: Option<&Bound<'py, PyTzInfo>>,
|
||||
) -> PyResult<Bound<'py, PyDateTime>> {
|
||||
PyDateTime::from_timestamp_bound(py, ts, tz)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_datetime_tzinfo(dt: &PyDateTime) -> Option<Bound<'_, PyTzInfo>> {
|
||||
fn get_datetime_tzinfo<'py>(dt: &Bound<'py, PyDateTime>) -> Option<Bound<'py, PyTzInfo>> {
|
||||
dt.get_tzinfo_bound()
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_time_tzinfo(dt: &PyTime) -> Option<Bound<'_, PyTzInfo>> {
|
||||
fn get_time_tzinfo<'py>(dt: &Bound<'py, PyTime>) -> Option<Bound<'py, PyTzInfo>> {
|
||||
dt.get_tzinfo_bound()
|
||||
}
|
||||
|
||||
|
@ -179,15 +187,19 @@ impl TzClass {
|
|||
TzClass {}
|
||||
}
|
||||
|
||||
fn utcoffset<'p>(&self, py: Python<'p>, _dt: &PyDateTime) -> PyResult<&'p PyDelta> {
|
||||
PyDelta::new(py, 0, 3600, 0, true)
|
||||
fn utcoffset<'py>(
|
||||
&self,
|
||||
py: Python<'py>,
|
||||
_dt: &Bound<'py, PyDateTime>,
|
||||
) -> PyResult<Bound<'py, PyDelta>> {
|
||||
PyDelta::new_bound(py, 0, 3600, 0, true)
|
||||
}
|
||||
|
||||
fn tzname(&self, _py: Python<'_>, _dt: &PyDateTime) -> String {
|
||||
fn tzname(&self, _dt: &Bound<'_, PyDateTime>) -> String {
|
||||
String::from("+01:00")
|
||||
}
|
||||
|
||||
fn dst(&self, _py: Python<'_>, _dt: &PyDateTime) -> Option<&PyDelta> {
|
||||
fn dst<'py>(&self, _dt: &Bound<'py, PyDateTime>) -> Option<Bound<'py, PyDelta>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,14 +47,12 @@ use crate::types::any::PyAnyMethods;
|
|||
use crate::types::datetime::timezone_from_offset;
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
use crate::types::{
|
||||
timezone_utc, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess,
|
||||
PyTzInfo, PyTzInfoAccess,
|
||||
timezone_utc_bound, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime,
|
||||
PyTimeAccess, PyTzInfo, PyTzInfoAccess,
|
||||
};
|
||||
#[cfg(Py_LIMITED_API)]
|
||||
use crate::{intern, DowncastError};
|
||||
use crate::{
|
||||
Bound, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject, PyResult, Python, ToPyObject,
|
||||
};
|
||||
use crate::{Bound, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject};
|
||||
use chrono::offset::{FixedOffset, Utc};
|
||||
use chrono::{
|
||||
DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike,
|
||||
|
@ -81,7 +79,7 @@ impl ToPyObject for Duration {
|
|||
// We pass true as the `normalize` parameter since we'd need to do several checks here to
|
||||
// avoid that, and it shouldn't have a big performance impact.
|
||||
// The seconds and microseconds cast should never overflow since it's at most the number of seconds per day
|
||||
PyDelta::new(
|
||||
PyDelta::new_bound(
|
||||
py,
|
||||
days.try_into().unwrap_or(i32::MAX),
|
||||
secs.try_into().unwrap(),
|
||||
|
@ -144,7 +142,7 @@ impl ToPyObject for NaiveDate {
|
|||
let DateArgs { year, month, day } = self.into();
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
{
|
||||
PyDate::new(py, year, month, day)
|
||||
PyDate::new_bound(py, year, month, day)
|
||||
.expect("failed to construct date")
|
||||
.into()
|
||||
}
|
||||
|
@ -189,15 +187,16 @@ impl ToPyObject for NaiveTime {
|
|||
truncated_leap_second,
|
||||
} = self.into();
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
let time = PyTime::new(py, hour, min, sec, micro, None).expect("Failed to construct time");
|
||||
let time =
|
||||
PyTime::new_bound(py, hour, min, sec, micro, None).expect("Failed to construct time");
|
||||
#[cfg(Py_LIMITED_API)]
|
||||
let time = DatetimeTypes::get(py)
|
||||
.time
|
||||
.as_ref(py)
|
||||
.bind(py)
|
||||
.call1((hour, min, sec, micro))
|
||||
.expect("failed to construct datetime.time");
|
||||
if truncated_leap_second {
|
||||
warn_truncated_leap_second(time);
|
||||
warn_truncated_leap_second(&time);
|
||||
}
|
||||
time.into()
|
||||
}
|
||||
|
@ -264,7 +263,7 @@ impl<Tz: TimeZone> ToPyObject for DateTime<Tz> {
|
|||
// FIXME: convert to better timezone representation here than just convert to fixed offset
|
||||
// See https://github.com/PyO3/pyo3/issues/3266
|
||||
let tz = self.offset().fix().to_object(py);
|
||||
let tz = tz.downcast(py).unwrap();
|
||||
let tz = tz.bind(py).downcast().unwrap();
|
||||
naive_datetime_to_py_datetime(py, &self.naive_local(), Some(tz))
|
||||
}
|
||||
}
|
||||
|
@ -310,9 +309,9 @@ impl ToPyObject for FixedOffset {
|
|||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
{
|
||||
let td = PyDelta::new(py, 0, seconds_offset, 0, true)
|
||||
let td = PyDelta::new_bound(py, 0, seconds_offset, 0, true)
|
||||
.expect("failed to construct timedelta");
|
||||
timezone_from_offset(py, td)
|
||||
timezone_from_offset(&td)
|
||||
.expect("Failed to construct PyTimezone")
|
||||
.into()
|
||||
}
|
||||
|
@ -366,7 +365,7 @@ impl FromPyObject<'_> for FixedOffset {
|
|||
|
||||
impl ToPyObject for Utc {
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
timezone_utc(py).into()
|
||||
timezone_utc_bound(py).into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,7 +377,7 @@ impl IntoPy<PyObject> for Utc {
|
|||
|
||||
impl FromPyObject<'_> for Utc {
|
||||
fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Utc> {
|
||||
let py_utc = timezone_utc(ob.py());
|
||||
let py_utc = timezone_utc_bound(ob.py());
|
||||
if ob.eq(py_utc)? {
|
||||
Ok(Utc)
|
||||
} else {
|
||||
|
@ -430,8 +429,8 @@ impl From<&NaiveTime> for TimeArgs {
|
|||
fn naive_datetime_to_py_datetime(
|
||||
py: Python<'_>,
|
||||
naive_datetime: &NaiveDateTime,
|
||||
#[cfg(not(Py_LIMITED_API))] tzinfo: Option<&PyTzInfo>,
|
||||
#[cfg(Py_LIMITED_API)] tzinfo: Option<&PyAny>,
|
||||
#[cfg(not(Py_LIMITED_API))] tzinfo: Option<&Bound<'_, PyTzInfo>>,
|
||||
#[cfg(Py_LIMITED_API)] tzinfo: Option<&Bound<'_, PyAny>>,
|
||||
) -> PyObject {
|
||||
let DateArgs { year, month, day } = (&naive_datetime.date()).into();
|
||||
let TimeArgs {
|
||||
|
@ -442,21 +441,21 @@ fn naive_datetime_to_py_datetime(
|
|||
truncated_leap_second,
|
||||
} = (&naive_datetime.time()).into();
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
let datetime = PyDateTime::new(py, year, month, day, hour, min, sec, micro, tzinfo)
|
||||
let datetime = PyDateTime::new_bound(py, year, month, day, hour, min, sec, micro, tzinfo)
|
||||
.expect("failed to construct datetime");
|
||||
#[cfg(Py_LIMITED_API)]
|
||||
let datetime = DatetimeTypes::get(py)
|
||||
.datetime
|
||||
.as_ref(py)
|
||||
.bind(py)
|
||||
.call1((year, month, day, hour, min, sec, micro, tzinfo))
|
||||
.expect("failed to construct datetime.datetime");
|
||||
if truncated_leap_second {
|
||||
warn_truncated_leap_second(datetime);
|
||||
warn_truncated_leap_second(&datetime);
|
||||
}
|
||||
datetime.into()
|
||||
}
|
||||
|
||||
fn warn_truncated_leap_second(obj: &PyAny) {
|
||||
fn warn_truncated_leap_second(obj: &Bound<'_, PyAny>) {
|
||||
let py = obj.py();
|
||||
if let Err(e) = PyErr::warn(
|
||||
py,
|
||||
|
@ -558,8 +557,8 @@ impl DatetimeTypes {
|
|||
}
|
||||
|
||||
#[cfg(Py_LIMITED_API)]
|
||||
fn timezone_utc(py: Python<'_>) -> &PyAny {
|
||||
DatetimeTypes::get(py).timezone_utc.as_ref(py)
|
||||
fn timezone_utc_bound(py: Python<'_>) -> Bound<'_, PyAny> {
|
||||
DatetimeTypes::get(py).timezone_utc.bind(py).clone()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -913,7 +912,7 @@ mod tests {
|
|||
let minute = 8;
|
||||
let second = 9;
|
||||
let micro = 999_999;
|
||||
let tz_utc = timezone_utc(py);
|
||||
let tz_utc = timezone_utc_bound(py);
|
||||
let py_datetime = new_py_datetime_ob(
|
||||
py,
|
||||
"datetime",
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::types::any::PyAnyMethods;
|
|||
#[cfg(Py_LIMITED_API)]
|
||||
use crate::types::PyType;
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
use crate::types::{timezone_utc, PyDateTime, PyDelta, PyDeltaAccess};
|
||||
use crate::types::{timezone_utc_bound, PyDateTime, PyDelta, PyDeltaAccess};
|
||||
#[cfg(Py_LIMITED_API)]
|
||||
use crate::Py;
|
||||
use crate::{
|
||||
|
@ -59,7 +59,7 @@ impl ToPyObject for Duration {
|
|||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
{
|
||||
PyDelta::new(
|
||||
PyDelta::new_bound(
|
||||
py,
|
||||
days.try_into()
|
||||
.expect("Too large Rust duration for timedelta"),
|
||||
|
@ -130,7 +130,18 @@ fn unix_epoch_py(py: Python<'_>) -> &PyObject {
|
|||
#[cfg(not(Py_LIMITED_API))]
|
||||
{
|
||||
Ok::<_, PyErr>(
|
||||
PyDateTime::new(py, 1970, 1, 1, 0, 0, 0, 0, Some(timezone_utc(py)))?.into(),
|
||||
PyDateTime::new_bound(
|
||||
py,
|
||||
1970,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
Some(&timezone_utc_bound(py)),
|
||||
)?
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
#[cfg(Py_LIMITED_API)]
|
||||
|
|
|
@ -77,11 +77,11 @@ fn test_utc_timezone() {
|
|||
#[cfg(feature = "macros")]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
fn test_timezone_from_offset() {
|
||||
use crate::types::PyDelta;
|
||||
use crate::{ffi_ptr_ext::FfiPtrExt, types::PyDelta};
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let delta = PyDelta::new(py, 0, 100, 0, false).unwrap();
|
||||
let tz: &PyAny = unsafe { py.from_borrowed_ptr(PyTimeZone_FromOffset(delta.as_ptr())) };
|
||||
let delta = PyDelta::new_bound(py, 0, 100, 0, false).unwrap();
|
||||
let tz = unsafe { PyTimeZone_FromOffset(delta.as_ptr()).assume_owned(py) };
|
||||
crate::py_run!(
|
||||
py,
|
||||
tz,
|
||||
|
@ -95,16 +95,13 @@ fn test_timezone_from_offset() {
|
|||
#[cfg(feature = "macros")]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
fn test_timezone_from_offset_and_name() {
|
||||
use crate::types::PyDelta;
|
||||
use crate::{ffi_ptr_ext::FfiPtrExt, types::PyDelta};
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let delta = PyDelta::new(py, 0, 100, 0, false).unwrap();
|
||||
let delta = PyDelta::new_bound(py, 0, 100, 0, false).unwrap();
|
||||
let tzname = PyString::new_bound(py, "testtz");
|
||||
let tz: &PyAny = unsafe {
|
||||
py.from_borrowed_ptr(PyTimeZone_FromOffsetAndName(
|
||||
delta.as_ptr(),
|
||||
tzname.as_ptr(),
|
||||
))
|
||||
let tz = unsafe {
|
||||
PyTimeZone_FromOffsetAndName(delta.as_ptr(), tzname.as_ptr()).assume_owned(py)
|
||||
};
|
||||
crate::py_run!(
|
||||
py,
|
||||
|
@ -253,36 +250,36 @@ fn ucs4() {
|
|||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
#[cfg(not(PyPy))]
|
||||
fn test_get_tzinfo() {
|
||||
use crate::types::timezone_utc;
|
||||
use crate::types::timezone_utc_bound;
|
||||
|
||||
crate::Python::with_gil(|py| {
|
||||
use crate::types::{PyDateTime, PyTime};
|
||||
use crate::PyAny;
|
||||
|
||||
let utc = timezone_utc(py);
|
||||
let utc = &timezone_utc_bound(py);
|
||||
|
||||
let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, Some(utc)).unwrap();
|
||||
let dt = PyDateTime::new_bound(py, 2018, 1, 1, 0, 0, 0, 0, Some(utc)).unwrap();
|
||||
|
||||
assert!(
|
||||
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_DATE_GET_TZINFO(dt.as_ptr())) }
|
||||
.is(utc)
|
||||
);
|
||||
|
||||
let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, None).unwrap();
|
||||
let dt = PyDateTime::new_bound(py, 2018, 1, 1, 0, 0, 0, 0, None).unwrap();
|
||||
|
||||
assert!(
|
||||
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_DATE_GET_TZINFO(dt.as_ptr())) }
|
||||
.is_none()
|
||||
);
|
||||
|
||||
let t = PyTime::new(py, 0, 0, 0, 0, Some(utc)).unwrap();
|
||||
let t = PyTime::new_bound(py, 0, 0, 0, 0, Some(utc)).unwrap();
|
||||
|
||||
assert!(
|
||||
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_TIME_GET_TZINFO(t.as_ptr())) }
|
||||
.is(utc)
|
||||
);
|
||||
|
||||
let t = PyTime::new(py, 0, 0, 0, 0, None).unwrap();
|
||||
let t = PyTime::new_bound(py, 0, 0, 0, 0, None).unwrap();
|
||||
|
||||
assert!(
|
||||
unsafe { py.from_borrowed_ptr::<PyAny>(PyDateTime_TIME_GET_TZINFO(t.as_ptr())) }
|
||||
|
|
|
@ -21,6 +21,7 @@ use crate::ffi::{
|
|||
};
|
||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::py_result_ext::PyResultExt;
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::types::PyTuple;
|
||||
use crate::{Bound, IntoPy, Py, PyAny, PyErr, Python};
|
||||
|
@ -201,27 +202,53 @@ pyobject_native_type!(
|
|||
);
|
||||
|
||||
impl PyDate {
|
||||
/// Creates a new `datetime.date`.
|
||||
/// Deprecated form of [`PyDate::new_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyDate::new` will be replaced by `PyDate::new_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn new(py: Python<'_>, year: i32, month: u8, day: u8) -> PyResult<&PyDate> {
|
||||
Self::new_bound(py, year, month, day).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Creates a new `datetime.date`.
|
||||
pub fn new_bound(py: Python<'_>, year: i32, month: u8, day: u8) -> PyResult<Bound<'_, PyDate>> {
|
||||
let api = ensure_datetime_api(py)?;
|
||||
unsafe {
|
||||
let ptr = (api.Date_FromDate)(year, c_int::from(month), c_int::from(day), api.DateType);
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
(api.Date_FromDate)(year, c_int::from(month), c_int::from(day), api.DateType)
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Deprecated form of [`PyDate::from_timestamp_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyDate::from_timestamp` will be replaced by `PyDate::from_timestamp_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn from_timestamp(py: Python<'_>, timestamp: i64) -> PyResult<&PyDate> {
|
||||
Self::from_timestamp_bound(py, timestamp).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Construct a `datetime.date` from a POSIX timestamp
|
||||
///
|
||||
/// This is equivalent to `datetime.date.fromtimestamp`
|
||||
pub fn from_timestamp(py: Python<'_>, timestamp: i64) -> PyResult<&PyDate> {
|
||||
pub fn from_timestamp_bound(py: Python<'_>, timestamp: i64) -> PyResult<Bound<'_, PyDate>> {
|
||||
let time_tuple = PyTuple::new_bound(py, [timestamp]);
|
||||
|
||||
// safety ensure that the API is loaded
|
||||
let _api = ensure_datetime_api(py)?;
|
||||
|
||||
unsafe {
|
||||
let ptr = PyDate_FromTimestamp(time_tuple.as_ptr());
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
PyDate_FromTimestamp(time_tuple.as_ptr())
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,10 +293,17 @@ pyobject_native_type!(
|
|||
);
|
||||
|
||||
impl PyDateTime {
|
||||
/// Creates a new `datetime.datetime` object.
|
||||
/// Deprecated form of [`PyDateTime::new_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyDateTime::new` will be replaced by `PyDateTime::new_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new<'p>(
|
||||
py: Python<'p>,
|
||||
pub fn new<'py>(
|
||||
py: Python<'py>,
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
|
@ -277,11 +311,38 @@ impl PyDateTime {
|
|||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
) -> PyResult<&'p PyDateTime> {
|
||||
tzinfo: Option<&'py PyTzInfo>,
|
||||
) -> PyResult<&'py PyDateTime> {
|
||||
Self::new_bound(
|
||||
py,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
microsecond,
|
||||
tzinfo.map(PyTzInfo::as_borrowed).as_deref(),
|
||||
)
|
||||
.map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Creates a new `datetime.datetime` object.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_bound<'py>(
|
||||
py: Python<'py>,
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
) -> PyResult<Bound<'py, PyDateTime>> {
|
||||
let api = ensure_datetime_api(py)?;
|
||||
unsafe {
|
||||
let ptr = (api.DateTime_FromDateAndTime)(
|
||||
(api.DateTime_FromDateAndTime)(
|
||||
year,
|
||||
c_int::from(month),
|
||||
c_int::from(day),
|
||||
|
@ -291,11 +352,48 @@ impl PyDateTime {
|
|||
microsecond as c_int,
|
||||
opt_to_pyobj(tzinfo),
|
||||
api.DateTimeType,
|
||||
);
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
)
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Deprecated form of [`PyDateTime::new_bound_with_fold`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyDateTime::new_with_fold` will be replaced by `PyDateTime::new_bound_with_fold` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_with_fold<'py>(
|
||||
py: Python<'py>,
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&'py PyTzInfo>,
|
||||
fold: bool,
|
||||
) -> PyResult<&'py PyDateTime> {
|
||||
Self::new_bound_with_fold(
|
||||
py,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
microsecond,
|
||||
tzinfo.map(PyTzInfo::as_borrowed).as_deref(),
|
||||
fold,
|
||||
)
|
||||
.map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Alternate constructor that takes a `fold` parameter. A `true` value for this parameter
|
||||
/// signifies this this datetime is the later of two moments with the same representation,
|
||||
/// during a repeated interval.
|
||||
|
@ -304,8 +402,8 @@ impl PyDateTime {
|
|||
/// represented time is ambiguous.
|
||||
/// See [PEP 495](https://www.python.org/dev/peps/pep-0495/) for more detail.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_with_fold<'p>(
|
||||
py: Python<'p>,
|
||||
pub fn new_bound_with_fold<'py>(
|
||||
py: Python<'py>,
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
|
@ -313,12 +411,12 @@ impl PyDateTime {
|
|||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
fold: bool,
|
||||
) -> PyResult<&'p PyDateTime> {
|
||||
) -> PyResult<Bound<'py, PyDateTime>> {
|
||||
let api = ensure_datetime_api(py)?;
|
||||
unsafe {
|
||||
let ptr = (api.DateTime_FromDateAndTimeAndFold)(
|
||||
(api.DateTime_FromDateAndTimeAndFold)(
|
||||
year,
|
||||
c_int::from(month),
|
||||
c_int::from(day),
|
||||
|
@ -329,27 +427,46 @@ impl PyDateTime {
|
|||
opt_to_pyobj(tzinfo),
|
||||
c_int::from(fold),
|
||||
api.DateTimeType,
|
||||
);
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
)
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Deprecated form of [`PyDateTime::from_timestamp_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyDateTime::from_timestamp` will be replaced by `PyDateTime::from_timestamp_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn from_timestamp<'py>(
|
||||
py: Python<'py>,
|
||||
timestamp: f64,
|
||||
tzinfo: Option<&'py PyTzInfo>,
|
||||
) -> PyResult<&'py PyDateTime> {
|
||||
Self::from_timestamp_bound(py, timestamp, tzinfo.map(PyTzInfo::as_borrowed).as_deref())
|
||||
.map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Construct a `datetime` object from a POSIX timestamp
|
||||
///
|
||||
/// This is equivalent to `datetime.datetime.fromtimestamp`
|
||||
pub fn from_timestamp<'p>(
|
||||
py: Python<'p>,
|
||||
pub fn from_timestamp_bound<'py>(
|
||||
py: Python<'py>,
|
||||
timestamp: f64,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
) -> PyResult<&'p PyDateTime> {
|
||||
let args: Py<PyTuple> = (timestamp, tzinfo).into_py(py);
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
) -> PyResult<Bound<'py, PyDateTime>> {
|
||||
let args = IntoPy::<Py<PyTuple>>::into_py((timestamp, tzinfo), py).into_bound(py);
|
||||
|
||||
// safety ensure API is loaded
|
||||
let _api = ensure_datetime_api(py)?;
|
||||
|
||||
unsafe {
|
||||
let ptr = PyDateTime_FromTimestamp(args.as_ptr());
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
PyDateTime_FromTimestamp(args.as_ptr())
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -463,42 +580,99 @@ pyobject_native_type!(
|
|||
);
|
||||
|
||||
impl PyTime {
|
||||
/// Creates a new `datetime.time` object.
|
||||
pub fn new<'p>(
|
||||
py: Python<'p>,
|
||||
/// Deprecated form of [`PyTime::new_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyTime::new` will be replaced by `PyTime::new_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn new<'py>(
|
||||
py: Python<'py>,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
) -> PyResult<&'p PyTime> {
|
||||
tzinfo: Option<&'py PyTzInfo>,
|
||||
) -> PyResult<&'py PyTime> {
|
||||
Self::new_bound(
|
||||
py,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
microsecond,
|
||||
tzinfo.map(PyTzInfo::as_borrowed).as_deref(),
|
||||
)
|
||||
.map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Creates a new `datetime.time` object.
|
||||
pub fn new_bound<'py>(
|
||||
py: Python<'py>,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
) -> PyResult<Bound<'py, PyTime>> {
|
||||
let api = ensure_datetime_api(py)?;
|
||||
unsafe {
|
||||
let ptr = (api.Time_FromTime)(
|
||||
(api.Time_FromTime)(
|
||||
c_int::from(hour),
|
||||
c_int::from(minute),
|
||||
c_int::from(second),
|
||||
microsecond as c_int,
|
||||
opt_to_pyobj(tzinfo),
|
||||
api.TimeType,
|
||||
);
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
)
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Alternate constructor that takes a `fold` argument. See [`PyDateTime::new_with_fold`].
|
||||
pub fn new_with_fold<'p>(
|
||||
py: Python<'p>,
|
||||
/// Deprecated form of [`PyTime::new_bound_with_fold`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyTime::new_with_fold` will be replaced by `PyTime::new_bound_with_fold` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn new_with_fold<'py>(
|
||||
py: Python<'py>,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&PyTzInfo>,
|
||||
tzinfo: Option<&'py PyTzInfo>,
|
||||
fold: bool,
|
||||
) -> PyResult<&'p PyTime> {
|
||||
) -> PyResult<&'py PyTime> {
|
||||
Self::new_bound_with_fold(
|
||||
py,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
microsecond,
|
||||
tzinfo.map(PyTzInfo::as_borrowed).as_deref(),
|
||||
fold,
|
||||
)
|
||||
.map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Alternate constructor that takes a `fold` argument. See [`PyDateTime::new_with_fold`].
|
||||
pub fn new_bound_with_fold<'py>(
|
||||
py: Python<'py>,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
microsecond: u32,
|
||||
tzinfo: Option<&Bound<'py, PyTzInfo>>,
|
||||
fold: bool,
|
||||
) -> PyResult<Bound<'py, PyTime>> {
|
||||
let api = ensure_datetime_api(py)?;
|
||||
unsafe {
|
||||
let ptr = (api.Time_FromTimeAndFold)(
|
||||
(api.Time_FromTimeAndFold)(
|
||||
c_int::from(hour),
|
||||
c_int::from(minute),
|
||||
c_int::from(second),
|
||||
|
@ -506,8 +680,9 @@ impl PyTime {
|
|||
opt_to_pyobj(tzinfo),
|
||||
fold as c_int,
|
||||
api.TimeType,
|
||||
);
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
)
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -596,20 +771,45 @@ pyobject_native_type!(
|
|||
#checkfunction=PyTZInfo_Check
|
||||
);
|
||||
|
||||
/// Equivalent to `datetime.timezone.utc`
|
||||
/// Deprecated form of [`timezone_utc_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`timezone_utc` will be replaced by `timezone_utc_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn timezone_utc(py: Python<'_>) -> &PyTzInfo {
|
||||
unsafe { &*(expect_datetime_api(py).TimeZone_UTC as *const PyTzInfo) }
|
||||
timezone_utc_bound(py).into_gil_ref()
|
||||
}
|
||||
|
||||
/// Equivalent to `datetime.timezone.utc`
|
||||
pub fn timezone_utc_bound(py: Python<'_>) -> Bound<'_, PyTzInfo> {
|
||||
// TODO: this _could_ have a borrowed form `timezone_utc_borrowed`, but that seems
|
||||
// like an edge case optimization and we'd prefer in PyO3 0.21 to use `Bound` as
|
||||
// much as possible
|
||||
unsafe {
|
||||
expect_datetime_api(py)
|
||||
.TimeZone_UTC
|
||||
.assume_borrowed(py)
|
||||
.to_owned()
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Equivalent to `datetime.timezone` constructor
|
||||
///
|
||||
/// Only used internally
|
||||
#[cfg(feature = "chrono")]
|
||||
pub fn timezone_from_offset<'a>(py: Python<'a>, offset: &PyDelta) -> PyResult<&'a PyTzInfo> {
|
||||
pub(crate) fn timezone_from_offset<'py>(
|
||||
offset: &Bound<'py, PyDelta>,
|
||||
) -> PyResult<Bound<'py, PyTzInfo>> {
|
||||
let py = offset.py();
|
||||
let api = ensure_datetime_api(py)?;
|
||||
unsafe {
|
||||
let ptr = (api.TimeZone_FromTimeZone)(offset.as_ptr(), ptr::null_mut());
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
(api.TimeZone_FromTimeZone)(offset.as_ptr(), ptr::null_mut())
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,7 +825,14 @@ pyobject_native_type!(
|
|||
);
|
||||
|
||||
impl PyDelta {
|
||||
/// Creates a new `timedelta`.
|
||||
/// Deprecated form of [`PyDelta::new_bound`].
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyDelta::new` will be replaced by `PyDelta::new_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn new(
|
||||
py: Python<'_>,
|
||||
days: i32,
|
||||
|
@ -633,16 +840,28 @@ impl PyDelta {
|
|||
microseconds: i32,
|
||||
normalize: bool,
|
||||
) -> PyResult<&PyDelta> {
|
||||
Self::new_bound(py, days, seconds, microseconds, normalize).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Creates a new `timedelta`.
|
||||
pub fn new_bound(
|
||||
py: Python<'_>,
|
||||
days: i32,
|
||||
seconds: i32,
|
||||
microseconds: i32,
|
||||
normalize: bool,
|
||||
) -> PyResult<Bound<'_, PyDelta>> {
|
||||
let api = ensure_datetime_api(py)?;
|
||||
unsafe {
|
||||
let ptr = (api.Delta_FromDelta)(
|
||||
(api.Delta_FromDelta)(
|
||||
days as c_int,
|
||||
seconds as c_int,
|
||||
microseconds as c_int,
|
||||
normalize as c_int,
|
||||
api.DeltaType,
|
||||
);
|
||||
py.from_owned_ptr_or_err(ptr)
|
||||
)
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -677,7 +896,7 @@ impl PyDeltaAccess for Bound<'_, PyDelta> {
|
|||
|
||||
// Utility function which returns a borrowed reference to either
|
||||
// the underlying tzinfo or None.
|
||||
fn opt_to_pyobj(opt: Option<&PyTzInfo>) -> *mut ffi::PyObject {
|
||||
fn opt_to_pyobj(opt: Option<&Bound<'_, PyTzInfo>>) -> *mut ffi::PyObject {
|
||||
match opt {
|
||||
Some(tzi) => tzi.as_ptr(),
|
||||
None => unsafe { ffi::Py_None() },
|
||||
|
@ -685,6 +904,7 @@ fn opt_to_pyobj(opt: Option<&PyTzInfo>) -> *mut ffi::PyObject {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[cfg(feature = "macros")]
|
||||
|
@ -768,7 +988,7 @@ mod tests {
|
|||
fn test_timezone_from_offset() {
|
||||
Python::with_gil(|py| {
|
||||
assert!(
|
||||
timezone_from_offset(py, PyDelta::new(py, 0, -3600, 0, true).unwrap())
|
||||
timezone_from_offset(&PyDelta::new_bound(py, 0, -3600, 0, true).unwrap())
|
||||
.unwrap()
|
||||
.call_method1("utcoffset", ((),))
|
||||
.unwrap()
|
||||
|
@ -779,7 +999,7 @@ mod tests {
|
|||
);
|
||||
|
||||
assert!(
|
||||
timezone_from_offset(py, PyDelta::new(py, 0, 3600, 0, true).unwrap())
|
||||
timezone_from_offset(&PyDelta::new_bound(py, 0, 3600, 0, true).unwrap())
|
||||
.unwrap()
|
||||
.call_method1("utcoffset", ((),))
|
||||
.unwrap()
|
||||
|
@ -789,7 +1009,7 @@ mod tests {
|
|||
.unwrap()
|
||||
);
|
||||
|
||||
timezone_from_offset(py, PyDelta::new(py, 1, 0, 0, true).unwrap()).unwrap_err();
|
||||
timezone_from_offset(&PyDelta::new_bound(py, 1, 0, 0, true).unwrap()).unwrap_err();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,13 @@ pub use self::capsule::PyCapsule;
|
|||
#[cfg(not(Py_LIMITED_API))]
|
||||
pub use self::code::PyCode;
|
||||
pub use self::complex::PyComplex;
|
||||
#[allow(deprecated)]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
pub use self::datetime::timezone_utc;
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
pub use self::datetime::{
|
||||
timezone_utc, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess,
|
||||
PyTzInfo, PyTzInfoAccess,
|
||||
timezone_utc_bound, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime,
|
||||
PyTimeAccess, PyTzInfo, PyTzInfoAccess,
|
||||
};
|
||||
pub use self::dict::{IntoPyDict, PyDict};
|
||||
#[cfg(not(PyPy))]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![cfg(not(Py_LIMITED_API))]
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::{timezone_utc, IntoPyDict, PyDate, PyDateTime, PyTime};
|
||||
use pyo3::types::{timezone_utc_bound, IntoPyDict, PyDate, PyDateTime, PyTime};
|
||||
use pyo3_ffi::PyDateTime_IMPORT;
|
||||
|
||||
fn _get_subclasses<'py>(
|
||||
|
@ -118,9 +118,9 @@ fn test_datetime_utc() {
|
|||
use pyo3::types::PyDateTime;
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let utc = timezone_utc(py);
|
||||
let utc = timezone_utc_bound(py);
|
||||
|
||||
let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, Some(utc)).unwrap();
|
||||
let dt = PyDateTime::new_bound(py, 2018, 1, 1, 0, 0, 0, 0, Some(&utc)).unwrap();
|
||||
|
||||
let locals = [("dt", dt)].into_py_dict_bound(py);
|
||||
|
||||
|
@ -155,7 +155,7 @@ fn test_pydate_out_of_bounds() {
|
|||
Python::with_gil(|py| {
|
||||
for val in INVALID_DATES {
|
||||
let (year, month, day) = val;
|
||||
let dt = PyDate::new(py, *year, *month, *day);
|
||||
let dt = PyDate::new_bound(py, *year, *month, *day);
|
||||
dt.unwrap_err();
|
||||
}
|
||||
});
|
||||
|
@ -168,7 +168,7 @@ fn test_pytime_out_of_bounds() {
|
|||
Python::with_gil(|py| {
|
||||
for val in INVALID_TIMES {
|
||||
let (hour, minute, second, microsecond) = val;
|
||||
let dt = PyTime::new(py, *hour, *minute, *second, *microsecond, None);
|
||||
let dt = PyTime::new_bound(py, *hour, *minute, *second, *microsecond, None);
|
||||
dt.unwrap_err();
|
||||
}
|
||||
});
|
||||
|
@ -192,7 +192,7 @@ fn test_pydatetime_out_of_bounds() {
|
|||
let (date, time) = val;
|
||||
let (year, month, day) = date;
|
||||
let (hour, minute, second, microsecond) = time;
|
||||
let dt = PyDateTime::new(
|
||||
let dt = PyDateTime::new_bound(
|
||||
py,
|
||||
*year,
|
||||
*month,
|
||||
|
|
|
@ -21,6 +21,6 @@ fn test_bad_datetime_module_panic() {
|
|||
.unwrap();
|
||||
|
||||
// This should panic because the "datetime" module is empty
|
||||
PyDate::new(py, 2018, 1, 1).unwrap();
|
||||
PyDate::new_bound(py, 2018, 1, 1).unwrap();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue