Add PyTime component accessors
This commit is contained in:
parent
ecf3aaafb2
commit
f701bccbdf
|
@ -108,6 +108,7 @@ pub struct PyDateTime_CAPI {
|
|||
// Type struct wrappers
|
||||
|
||||
const _PyDateTime_DATE_DATASIZE : usize = 4;
|
||||
const _PyDateTime_TIME_DATASIZE : usize = 6;
|
||||
const _PyDateTime_DATETIME_DATASIZE: usize = 10;
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -119,6 +120,18 @@ pub struct PyDateTime_Date {
|
|||
pub data: [c_uchar; _PyDateTime_DATE_DATASIZE],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct PyDateTime_Time {
|
||||
pub ob_base: PyObject,
|
||||
pub hashcode: Py_hash_t,
|
||||
pub hastzinfo: c_char,
|
||||
pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
|
||||
#[cfg(Py_3_6)]
|
||||
pub fold: c_uchar,
|
||||
pub tzinfo: *mut PyObject
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct PyDateTime_DateTime {
|
||||
|
@ -324,6 +337,38 @@ pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
|
|||
_PyDateTime_GET_TZINFO!(o as *mut PyDateTime_DateTime)
|
||||
}
|
||||
|
||||
// Accessor functions for Time
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int {
|
||||
_PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int {
|
||||
_PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int {
|
||||
_PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int {
|
||||
_PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0)
|
||||
}
|
||||
|
||||
#[cfg(Py_3_6)]
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar {
|
||||
_PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
|
||||
_PyDateTime_GET_TZINFO!(o as *mut PyDateTime_Time)
|
||||
}
|
||||
|
||||
|
||||
// Accessor functions for PyDateTime_Delta
|
||||
macro_rules! _access_delta_field {
|
||||
|
|
|
@ -6,6 +6,8 @@ use ffi::{PyDateTime_DateType, PyDate_Check};
|
|||
use ffi::{PyDateTime_Date_GET_YEAR, PyDateTime_Date_GET_MONTH, PyDateTime_Date_GET_DAY};
|
||||
use ffi::{PyDateTime_DateTimeType, PyDateTime_Check};
|
||||
use ffi::{PyDateTime_DateTime_GET_YEAR, PyDateTime_DateTime_GET_MONTH, PyDateTime_DateTime_GET_DAY};
|
||||
use ffi::{PyDateTime_TIME_GET_HOUR, PyDateTime_TIME_GET_MINUTE,
|
||||
PyDateTime_TIME_GET_SECOND, PyDateTime_TIME_GET_MICROSECOND};
|
||||
use ffi::{PyDateTime_DATE_GET_HOUR, PyDateTime_DATE_GET_MINUTE,
|
||||
PyDateTime_DATE_GET_SECOND, PyDateTime_DATE_GET_MICROSECOND};
|
||||
use ffi::{PyDateTime_DeltaType, PyDelta_Check};
|
||||
|
@ -14,7 +16,7 @@ use ffi::{PyDateTime_TimeType, PyTime_Check};
|
|||
use ffi::{PyDateTime_TZInfoType, PyTZInfo_Check};
|
||||
|
||||
#[cfg(Py_3_6)]
|
||||
use ffi::{PyDateTime_DATE_GET_FOLD};
|
||||
use ffi::{PyDateTime_DATE_GET_FOLD, PyDateTime_TIME_GET_FOLD};
|
||||
|
||||
use python::{Python, ToPyPointer};
|
||||
use instance::Py;
|
||||
|
@ -224,6 +226,40 @@ impl PyTime {
|
|||
|
||||
}
|
||||
|
||||
impl PyTimeComponentAccess for PyTime {
|
||||
fn get_hour(&self) -> u32 {
|
||||
unsafe {
|
||||
PyDateTime_TIME_GET_HOUR(self.as_ptr()) as u32
|
||||
}
|
||||
}
|
||||
|
||||
fn get_minute(&self) -> u32 {
|
||||
unsafe {
|
||||
PyDateTime_TIME_GET_MINUTE(self.as_ptr()) as u32
|
||||
}
|
||||
}
|
||||
|
||||
fn get_second(&self) -> u32 {
|
||||
unsafe {
|
||||
PyDateTime_TIME_GET_SECOND(self.as_ptr()) as u32
|
||||
}
|
||||
}
|
||||
|
||||
fn get_microsecond(&self) -> u32 {
|
||||
unsafe {
|
||||
PyDateTime_TIME_GET_MICROSECOND(self.as_ptr()) as u32
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(Py_3_6)]
|
||||
fn get_fold(&self) -> u8 {
|
||||
unsafe {
|
||||
PyDateTime_TIME_GET_FOLD(self.as_ptr()) as u8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// datetime.tzinfo bindings
|
||||
pub struct PyTzInfo(PyObject);
|
||||
pyobject_native_type!(PyTzInfo, PyDateTime_TZInfoType, PyTZInfo_Check);
|
||||
|
|
|
@ -46,6 +46,28 @@ fn make_time(py: Python, hour: u32, minute: u32, second: u32,
|
|||
PyTime::new(py, hour, minute, second, microsecond, &tzi)
|
||||
}
|
||||
|
||||
#[cfg(Py_3_6)]
|
||||
#[pyfunction]
|
||||
fn time_with_fold(py: Python, hour: u32, minute: u32, second: u32,
|
||||
microsecond: u32, tzinfo: Option<&PyTzInfo>,
|
||||
fold: bool) -> PyResult<Py<PyTime>> {
|
||||
let tzi = to_pyobject!(py, tzinfo);
|
||||
PyTime::new_with_fold(py, hour, minute, second, microsecond, &tzi, fold)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn get_time_tuple(py: Python, dt: &PyTime) -> Py<PyTuple> {
|
||||
PyTuple::new(py, &[dt.get_hour(), dt.get_minute(), dt.get_second(),
|
||||
dt.get_microsecond()])
|
||||
}
|
||||
|
||||
#[cfg(Py_3_6)]
|
||||
#[pyfunction]
|
||||
fn get_time_tuple_fold(py: Python, dt: &PyTime) -> Py<PyTuple> {
|
||||
PyTuple::new(py, &[dt.get_hour(), dt.get_minute(), dt.get_second(),
|
||||
dt.get_microsecond(), dt.get_fold() as u32])
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn make_delta(py: Python, days: i32, seconds: i32, microseconds: i32) -> PyResult<Py<PyDelta>> {
|
||||
PyDelta::new(py, days, seconds, microseconds, true)
|
||||
|
@ -97,14 +119,6 @@ fn datetime_from_timestamp(py: Python, ts: f64, tz: Option<&PyTzInfo>) -> PyResu
|
|||
}
|
||||
|
||||
|
||||
#[cfg(Py_3_6)]
|
||||
#[pyfunction]
|
||||
fn time_with_fold(py: Python, hour: u32, minute: u32, second: u32,
|
||||
microsecond: u32, tzinfo: Option<&PyTzInfo>,
|
||||
fold: bool) -> PyResult<Py<PyTime>> {
|
||||
let tzi = to_pyobject!(py, tzinfo);
|
||||
PyTime::new_with_fold(py, hour, minute, second, microsecond, &tzi, fold)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -114,6 +128,7 @@ fn datetime(_py: Python, m: &PyModule) -> PyResult<()> {
|
|||
m.add_function(wrap_function!(get_date_tuple))?;
|
||||
m.add_function(wrap_function!(date_from_timestamp))?;
|
||||
m.add_function(wrap_function!(make_time))?;
|
||||
m.add_function(wrap_function!(get_time_tuple))?;
|
||||
m.add_function(wrap_function!(make_delta))?;
|
||||
m.add_function(wrap_function!(get_delta_tuple))?;
|
||||
m.add_function(wrap_function!(make_datetime))?;
|
||||
|
@ -124,6 +139,7 @@ fn datetime(_py: Python, m: &PyModule) -> PyResult<()> {
|
|||
#[cfg(Py_3_6)]
|
||||
{
|
||||
m.add_function(wrap_function!(time_with_fold));
|
||||
m.add_function(wrap_function!(get_time_tuple_fold));
|
||||
m.add_function(wrap_function!(get_datetime_tuple_fold));
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,27 @@ def test_time(args, kwargs):
|
|||
assert act.tzinfo is exp.tzinfo
|
||||
|
||||
|
||||
@given(t=st.times())
|
||||
def test_time(t):
|
||||
act = rdt.get_time_tuple(t)
|
||||
exp = (t.hour, t.minute, t.second, t.microsecond)
|
||||
|
||||
assert act == exp
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6")
|
||||
@given(t=st.times())
|
||||
def test_time_fold(t):
|
||||
t_nofold = t.replace(fold=0)
|
||||
t_fold = t.replace(fold=1)
|
||||
|
||||
for t in (t_nofold, t_fold):
|
||||
act = rdt.get_time_tuple_fold(t)
|
||||
exp = (t.hour, t.minute, t.second, t.microsecond, t.fold)
|
||||
|
||||
assert act == exp
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6")
|
||||
@pytest.mark.parametrize('fold', [False, True])
|
||||
def test_time_fold(fold):
|
||||
|
@ -130,8 +151,8 @@ def test_datetime_tuple(dt):
|
|||
@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6")
|
||||
@given(dt=st.datetimes())
|
||||
def test_datetime_tuple_fold(dt):
|
||||
dt_fold = dt.replace(fold=0)
|
||||
dt_nofold = dt.replace(fold=1)
|
||||
dt_fold = dt.replace(fold=1)
|
||||
dt_nofold = dt.replace(fold=0)
|
||||
|
||||
for dt in (dt_fold, dt_nofold):
|
||||
act = rdt.get_datetime_tuple_fold(dt)
|
||||
|
|
Loading…
Reference in a new issue