Add PyDelta component accessors
Adds the PyDateTime_DELTA_GET_{comp} accessors and bindings to them in the PyDelta object.
This commit is contained in:
parent
149a13cbfa
commit
08e7e0f55a
|
@ -1,6 +1,7 @@
|
|||
use std::os::raw::c_int;
|
||||
use std::ffi::CString;
|
||||
use std::option::Option;
|
||||
use ffi3::pyport::Py_hash_t;
|
||||
use ffi3::object::*;
|
||||
use ffi3::pycapsule::PyCapsule_Import;
|
||||
|
||||
|
@ -104,6 +105,16 @@ pub struct PyDateTime_CAPI {
|
|||
>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct PyDateTime_Delta {
|
||||
pub ob_base: PyObject,
|
||||
pub hashcode: Py_hash_t,
|
||||
pub days: c_int,
|
||||
pub seconds: c_int,
|
||||
pub microseconds: c_int,
|
||||
}
|
||||
|
||||
unsafe impl Sync for PyDateTime_CAPI {}
|
||||
|
||||
lazy_static! {
|
||||
|
@ -145,3 +156,34 @@ pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int {
|
|||
pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int {
|
||||
PyObject_TypeCheck(op, PyDateTimeAPI.DeltaType) as c_int
|
||||
}
|
||||
|
||||
//
|
||||
// Accessor functions
|
||||
//
|
||||
macro_rules! _access_field {
|
||||
($obj:expr, $type: ident, $field:tt) => {
|
||||
(*($obj as *mut $type)).$field
|
||||
}
|
||||
}
|
||||
|
||||
// Accessor functions for PyDateTime_Delta
|
||||
macro_rules! _access_delta_field {
|
||||
($obj:expr, $field:tt) => {
|
||||
_access_field!($obj, PyDateTime_Delta, $field)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int {
|
||||
_access_delta_field!(o, days)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int {
|
||||
_access_delta_field!(o, seconds)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int {
|
||||
_access_delta_field!(o, microseconds)
|
||||
}
|
||||
|
|
|
@ -5,12 +5,19 @@ use ffi::{PyDateTimeAPI};
|
|||
use ffi::{PyDateTime_DateType, PyDate_Check};
|
||||
use ffi::{PyDateTime_DateTimeType, PyDateTime_Check};
|
||||
use ffi::{PyDateTime_DeltaType, PyDelta_Check};
|
||||
use ffi::{PyDateTime_DELTA_GET_DAYS, PyDateTime_DELTA_GET_SECONDS, PyDateTime_DELTA_GET_MICROSECONDS};
|
||||
use ffi::{PyDateTime_TimeType, PyTime_Check};
|
||||
use ffi::{PyDateTime_TZInfoType, PyTZInfo_Check};
|
||||
use python::{Python, ToPyPointer};
|
||||
use instance::Py;
|
||||
|
||||
|
||||
pub trait PyDeltaComponentAccess {
|
||||
fn get_days(&self) -> i32;
|
||||
fn get_seconds(&self) -> i32;
|
||||
fn get_microseconds(&self) -> i32;
|
||||
}
|
||||
|
||||
|
||||
// datetime.date bindings
|
||||
pub struct PyDate(PyObject);
|
||||
|
@ -142,3 +149,22 @@ impl PyDelta {
|
|||
}
|
||||
}
|
||||
|
||||
impl PyDeltaComponentAccess for PyDelta {
|
||||
fn get_days(&self) -> i32 {
|
||||
unsafe {
|
||||
PyDateTime_DELTA_GET_DAYS(self.as_ptr()) as i32
|
||||
}
|
||||
}
|
||||
|
||||
fn get_seconds(&self) -> i32 {
|
||||
unsafe {
|
||||
PyDateTime_DELTA_GET_SECONDS(self.as_ptr()) as i32
|
||||
}
|
||||
}
|
||||
|
||||
fn get_microseconds(&self) -> i32 {
|
||||
unsafe {
|
||||
PyDateTime_DELTA_GET_MICROSECONDS(self.as_ptr()) as i32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ mod exc_impl;
|
|||
pub use self::boolobject::PyBool;
|
||||
pub use self::bytearray::PyByteArray;
|
||||
pub use self::datetime::{PyDate,PyTime,PyDateTime,PyDelta,PyTzInfo};
|
||||
pub use self::datetime::{PyDeltaComponentAccess};
|
||||
pub use self::dict::PyDict;
|
||||
pub use self::floatob::PyFloat;
|
||||
pub use self::iterator::PyIterator;
|
||||
|
|
|
@ -9,6 +9,7 @@ use pyo3::prelude::{pyfunction, pymodinit};
|
|||
use pyo3::prelude::{PyObject};
|
||||
use pyo3::prelude::{PyModule};
|
||||
use pyo3::prelude::{PyDate, PyTime, PyDateTime, PyDelta, PyTzInfo};
|
||||
use pyo3::prelude::{PyDeltaComponentAccess};
|
||||
use pyo3::prelude::{PyTuple, PyDict};
|
||||
|
||||
|
||||
|
@ -44,6 +45,11 @@ fn make_delta(py: Python, days: i32, seconds: i32, microseconds: i32) -> PyResul
|
|||
PyDelta::new(py, days, seconds, microseconds, true)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_delta_tuple(py: Python, delta: &PyDelta) -> Py<PyTuple> {
|
||||
PyTuple::new(py, &[delta.get_days(), delta.get_seconds(), delta.get_microseconds()])
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn make_datetime(py: Python, year: u32, month: u32, day: u32,
|
||||
hour: u32, minute: u32, second: u32, microsecond: u32,
|
||||
|
@ -87,6 +93,7 @@ fn datetime(_py: Python, m: &PyModule) -> PyResult<()> {
|
|||
m.add_function(wrap_function!(date_from_timestamp))?;
|
||||
m.add_function(wrap_function!(make_time))?;
|
||||
m.add_function(wrap_function!(make_delta))?;
|
||||
m.add_function(wrap_function!(get_delta_tuple))?;
|
||||
m.add_function(wrap_function!(make_datetime))?;
|
||||
m.add_function(wrap_function!(datetime_from_timestamp))?;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import datetime as pdt
|
|||
import pytest
|
||||
|
||||
from hypothesis import given
|
||||
from hypothesis import strategies as st
|
||||
from hypothesis.strategies import dates, datetimes
|
||||
|
||||
# Constants
|
||||
|
@ -152,6 +153,14 @@ def test_delta(args):
|
|||
assert act == exp
|
||||
|
||||
|
||||
@given(td=st.timedeltas())
|
||||
def test_delta_accessors(td):
|
||||
act = rdt.get_delta_tuple(td)
|
||||
exp = (td.days, td.seconds, td.microseconds)
|
||||
|
||||
assert act == exp
|
||||
|
||||
|
||||
@pytest.mark.parametrize('args,err_type', [
|
||||
((MAX_DAYS + 1, 0, 0), OverflowError),
|
||||
((MIN_DAYS - 1, 0, 0), OverflowError),
|
||||
|
|
Loading…
Reference in a new issue