Add datetime.time
This commit is contained in:
parent
d7b90c1b3a
commit
f45362943d
|
@ -130,3 +130,8 @@ pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int {
|
||||||
pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int {
|
pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int {
|
||||||
PyObject_TypeCheck(op, PyDateTimeAPI.TZInfoType) as c_int
|
PyObject_TypeCheck(op, PyDateTimeAPI.TZInfoType) as c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int {
|
||||||
|
PyObject_TypeCheck(op, PyDateTimeAPI.TimeType) as c_int
|
||||||
|
}
|
||||||
|
|
|
@ -54,6 +54,29 @@ impl PyDateTime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// datetime.time
|
||||||
|
pub struct PyTime(PyObject);
|
||||||
|
pyobject_convert!(PyTime);
|
||||||
|
pyobject_nativetype!(PyTime, PyDateTime_TimeType, PyTime_Check);
|
||||||
|
|
||||||
|
impl PyTime {
|
||||||
|
pub fn new(py: Python, hour: u32, minute: u32, second: u32,
|
||||||
|
microsecond: u32, tzinfo: &PyObject) -> PyResult<Py<PyTime>> {
|
||||||
|
let h = hour as c_int;
|
||||||
|
let m = minute as c_int;
|
||||||
|
let s = second as c_int;
|
||||||
|
let u = microsecond as c_int;
|
||||||
|
let tzi = tzinfo.as_ptr();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let ptr = PyDateTimeAPI.Time_FromTime.unwrap()(
|
||||||
|
h, m, s, u, tzi, PyDateTimeAPI.TimeType
|
||||||
|
);
|
||||||
|
Py::from_owned_ptr_or_err(py, ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// datetime.tzinfo bindings
|
// datetime.tzinfo bindings
|
||||||
pub struct PyTzInfo(PyObject);
|
pub struct PyTzInfo(PyObject);
|
||||||
pyobject_convert!(PyTzInfo);
|
pyobject_convert!(PyTzInfo);
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod exc_impl;
|
||||||
|
|
||||||
pub use self::boolobject::PyBool;
|
pub use self::boolobject::PyBool;
|
||||||
pub use self::bytearray::PyByteArray;
|
pub use self::bytearray::PyByteArray;
|
||||||
pub use self::datetime::{PyDate,PyDateTime,PyTzInfo};
|
pub use self::datetime::{PyDate,PyTime,PyDateTime,PyTzInfo};
|
||||||
pub use self::dict::PyDict;
|
pub use self::dict::PyDict;
|
||||||
pub use self::floatob::PyFloat;
|
pub use self::floatob::PyFloat;
|
||||||
pub use self::iterator::PyIterator;
|
pub use self::iterator::PyIterator;
|
||||||
|
|
|
@ -4,7 +4,7 @@ extern crate pyo3;
|
||||||
use pyo3::{py, Py, Python, PyModule, PyResult};
|
use pyo3::{py, Py, Python, PyModule, PyResult};
|
||||||
use pyo3::{ToPyObject};
|
use pyo3::{ToPyObject};
|
||||||
use pyo3::prelude::{PyObject};
|
use pyo3::prelude::{PyObject};
|
||||||
use pyo3::prelude::{PyDate, PyDateTime, PyTzInfo};
|
use pyo3::prelude::{PyDate, PyTime, PyDateTime, PyTzInfo};
|
||||||
|
|
||||||
#[py::modinit(datetime)]
|
#[py::modinit(datetime)]
|
||||||
fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
|
@ -13,6 +13,17 @@ fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
PyDate::new(py, year, month, day)
|
PyDate::new(py, year, month, day)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyfn(m, "make_time")]
|
||||||
|
fn make_time(py: Python, hour: u32, minute: u32, second: u32,
|
||||||
|
microsecond: u32, tzinfo: Option<&PyTzInfo>) -> PyResult<Py<PyTime>> {
|
||||||
|
let tzi: PyObject = match tzinfo {
|
||||||
|
Some(t) => t.to_object(py),
|
||||||
|
None => py.None(),
|
||||||
|
};
|
||||||
|
|
||||||
|
PyTime::new(py, hour, minute, second, microsecond, &tzi)
|
||||||
|
}
|
||||||
|
|
||||||
#[pyfn(m, "make_datetime")]
|
#[pyfn(m, "make_datetime")]
|
||||||
fn make_datetime(py: Python, year: u32, month: u32, day: u32,
|
fn make_datetime(py: Python, year: u32, month: u32, day: u32,
|
||||||
hour: u32, minute: u32, second: u32, microsecond: u32,
|
hour: u32, minute: u32, second: u32, microsecond: u32,
|
||||||
|
|
|
@ -4,6 +4,8 @@ import datetime as pdt
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
UTC = pdt.timezone.utc
|
||||||
|
|
||||||
|
|
||||||
def test_date():
|
def test_date():
|
||||||
assert rdt.make_date(2017, 9, 1) == pdt.date(2017, 9, 1)
|
assert rdt.make_date(2017, 9, 1) == pdt.date(2017, 9, 1)
|
||||||
|
@ -14,15 +16,67 @@ def test_invalid_date_fails():
|
||||||
rdt.make_date(2017, 2, 30)
|
rdt.make_date(2017, 2, 30)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('args, kwargs', [
|
||||||
|
((0, 0, 0, 0, None), {}),
|
||||||
|
((1, 12, 14, 124731), {}),
|
||||||
|
((1, 12, 14, 124731), {'tzinfo': UTC}),
|
||||||
|
])
|
||||||
|
def test_time(args, kwargs):
|
||||||
|
act = rdt.make_time(*args, **kwargs)
|
||||||
|
exp = pdt.time(*args, **kwargs)
|
||||||
|
|
||||||
|
assert act == exp
|
||||||
|
assert act.tzinfo is exp.tzinfo
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail
|
||||||
|
@pytest.mark.parametrize('args', [
|
||||||
|
(-1, 0, 0, 0),
|
||||||
|
(0, -1, 0, 0),
|
||||||
|
(0, 0, -1, 0),
|
||||||
|
(0, 0, 0, -1),
|
||||||
|
])
|
||||||
|
def test_invalid_time_fails_xfail(args):
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
rdt.make_time(*args)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('args', [
|
||||||
|
(24, 0, 0, 0),
|
||||||
|
(25, 0, 0, 0),
|
||||||
|
(0, 60, 0, 0),
|
||||||
|
(0, 61, 0, 0),
|
||||||
|
(0, 0, 60, 0),
|
||||||
|
(0, 0, 61, 0),
|
||||||
|
(0, 0, 0, 1000000)
|
||||||
|
])
|
||||||
|
def test_invalid_time_fails(args):
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
rdt.make_time(*args)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('args', [
|
||||||
|
('0', 0, 0, 0),
|
||||||
|
(0, '0', 0, 0),
|
||||||
|
(0, 0, '0', 0),
|
||||||
|
(0, 0, 0, '0'),
|
||||||
|
(0, 0, 0, 0, 'UTC')
|
||||||
|
])
|
||||||
|
def test_time_typeerror(args):
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
rdt.make_time(*args)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('args, kwargs', [
|
@pytest.mark.parametrize('args, kwargs', [
|
||||||
((2017, 9, 1, 12, 45, 30, 0), {}),
|
((2017, 9, 1, 12, 45, 30, 0), {}),
|
||||||
((2017, 9, 1, 12, 45, 30, 0), {'tzinfo': pdt.timezone.utc}),
|
((2017, 9, 1, 12, 45, 30, 0), {'tzinfo': UTC}),
|
||||||
])
|
])
|
||||||
def test_datetime(args, kwargs):
|
def test_datetime(args, kwargs):
|
||||||
act = rdt.make_datetime(*args, **kwargs)
|
act = rdt.make_datetime(*args, **kwargs)
|
||||||
exp = pdt.datetime(*args, **kwargs)
|
exp = pdt.datetime(*args, **kwargs)
|
||||||
|
|
||||||
assert act == exp
|
assert act == exp
|
||||||
|
assert act.tzinfo is exp.tzinfo
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_datetime_fails():
|
def test_invalid_datetime_fails():
|
||||||
|
|
Loading…
Reference in New Issue