Merge pull request #237 from kngwyu/datetime-fix

Datetime fix
This commit is contained in:
konstin 2018-09-28 22:48:45 +02:00 committed by GitHub
commit d42731a01b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 23 deletions

View File

@ -186,6 +186,29 @@ fn issue_219() -> PyResult<()> {
Ok(()) Ok(())
} }
#[pyclass(extends=PyTzInfo)]
pub struct TzClass {}
#[pymethods]
impl TzClass {
#[new]
fn __new__(obj: &PyRawObject) -> PyResult<()> {
obj.init(|_| TzClass {})
}
fn utcoffset(&self, py: Python, dt: &PyDateTime) -> PyResult<Py<PyDelta>> {
PyDelta::new(py, 0, 3600, 0, true)
}
fn tzname(&self, py: Python, dt: &PyDateTime) -> PyResult<String> {
Ok(String::from("+01:00"))
}
fn dst(&self, py: Python, dt: &PyDateTime) -> PyResult<Option<&PyDelta>> {
Ok(None)
}
}
#[pymodinit] #[pymodinit]
fn datetime(_py: Python, m: &PyModule) -> PyResult<()> { fn datetime(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_function!(make_date))?; m.add_function(wrap_function!(make_date))?;
@ -209,5 +232,6 @@ fn datetime(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_function!(issue_219))?; m.add_function(wrap_function!(issue_219))?;
m.add_class::<TzClass>()?;
Ok(()) Ok(())
} }

View File

@ -4,7 +4,6 @@ import sys
import datetime as pdt import datetime as pdt
import pytest import pytest
from hypothesis import given from hypothesis import given
from hypothesis import strategies as st from hypothesis import strategies as st
from hypothesis.strategies import dates, datetimes from hypothesis.strategies import dates, datetimes
@ -263,3 +262,12 @@ def test_delta_err(args, err_type):
def test_issue_219(): def test_issue_219():
rdt.issue_219() rdt.issue_219()
def test_tz_class():
tzi = rdt.TzClass()
dt = pdt.datetime(2018, 1, 1, tzinfo=tzi)
assert dt.tzname() == "+01:00"
assert dt.utcoffset() == pdt.timedelta(hours=1)
assert dt.dst() is None

View File

@ -1,9 +1,11 @@
#![cfg_attr(feature = "cargo-clippy", allow(type_complexity))] #![cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
//! FFI bindings to the functions and structs defined in `datetime.h` //! FFI bindings to the functions and structs defined in `datetime.h`
//! //!
//! This is the unsafe thin wrapper around the [CPython C API](https://docs.python.org/3/c-api/datetime.html), //! This is the unsafe thin wrapper around the [CPython C API](https://docs.python.org/3/c-api/datetime.html),
//! and covers the various date and time related objects in the Python `datetime` //! and covers the various date and time related objects in the Python `datetime`
//! standard library module. //! standard library module.
use ffi::PyCapsule_Import; use ffi::PyCapsule_Import;
use ffi::Py_hash_t; use ffi::Py_hash_t;
use ffi::{PyObject, PyTypeObject}; use ffi::{PyObject, PyTypeObject};
@ -14,16 +16,6 @@ use std::os::raw::{c_char, c_int, c_uchar};
use std::ptr; use std::ptr;
use std::sync::Once; use std::sync::Once;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyDateTime_DateType: PyTypeObject;
pub static mut PyDateTime_TimeType: PyTypeObject;
pub static mut PyDateTime_DateTimeType: PyTypeObject;
pub static mut PyDateTime_DeltaType: PyTypeObject;
pub static mut PyDateTime_TZInfoType: PyTypeObject;
}
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct PyDateTime_CAPI { pub struct PyDateTime_CAPI {

View File

@ -6,7 +6,7 @@ use conversion::ToPyObject;
use err::PyResult; use err::PyResult;
use ffi; use ffi;
use ffi::PyDateTimeAPI; use ffi::PyDateTimeAPI;
use ffi::{PyDateTime_Check, PyDateTime_DateTimeType}; use ffi::{PyDateTime_Check, PyDate_Check, PyDelta_Check, PyTZInfo_Check, PyTime_Check};
#[cfg(Py_3_6)] #[cfg(Py_3_6)]
use ffi::{PyDateTime_DATE_GET_FOLD, PyDateTime_TIME_GET_FOLD}; use ffi::{PyDateTime_DATE_GET_FOLD, PyDateTime_TIME_GET_FOLD};
use ffi::{ use ffi::{
@ -16,15 +16,11 @@ use ffi::{
use ffi::{ use ffi::{
PyDateTime_DELTA_GET_DAYS, PyDateTime_DELTA_GET_MICROSECONDS, PyDateTime_DELTA_GET_SECONDS, PyDateTime_DELTA_GET_DAYS, PyDateTime_DELTA_GET_MICROSECONDS, PyDateTime_DELTA_GET_SECONDS,
}; };
use ffi::{PyDateTime_DateType, PyDate_Check};
use ffi::{PyDateTime_DeltaType, PyDelta_Check};
use ffi::{PyDateTime_GET_DAY, PyDateTime_GET_MONTH, PyDateTime_GET_YEAR}; use ffi::{PyDateTime_GET_DAY, PyDateTime_GET_MONTH, PyDateTime_GET_YEAR};
use ffi::{ use ffi::{
PyDateTime_TIME_GET_HOUR, PyDateTime_TIME_GET_MICROSECOND, PyDateTime_TIME_GET_MINUTE, PyDateTime_TIME_GET_HOUR, PyDateTime_TIME_GET_MICROSECOND, PyDateTime_TIME_GET_MINUTE,
PyDateTime_TIME_GET_SECOND, PyDateTime_TIME_GET_SECOND,
}; };
use ffi::{PyDateTime_TZInfoType, PyTZInfo_Check};
use ffi::{PyDateTime_TimeType, PyTime_Check};
use instance::Py; use instance::Py;
use object::PyObject; use object::PyObject;
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
@ -64,7 +60,7 @@ pub trait PyTimeAccess {
/// Bindings around `datetime.date` /// Bindings around `datetime.date`
pub struct PyDate(PyObject); pub struct PyDate(PyObject);
pyobject_native_type!(PyDate, PyDateTime_DateType, PyDate_Check); pyobject_native_type!(PyDate, *PyDateTimeAPI.DateType, PyDate_Check);
impl PyDate { impl PyDate {
pub fn new(py: Python, year: i32, month: u8, day: u8) -> PyResult<Py<PyDate>> { pub fn new(py: Python, year: i32, month: u8, day: u8) -> PyResult<Py<PyDate>> {
@ -108,7 +104,7 @@ impl PyDateAccess for PyDate {
/// Bindings for `datetime.datetime` /// Bindings for `datetime.datetime`
pub struct PyDateTime(PyObject); pub struct PyDateTime(PyObject);
pyobject_native_type!(PyDateTime, PyDateTime_DateTimeType, PyDateTime_Check); pyobject_native_type!(PyDateTime, *PyDateTimeAPI.DateTimeType, PyDateTime_Check);
impl PyDateTime { impl PyDateTime {
pub fn new( pub fn new(
@ -205,7 +201,7 @@ impl PyTimeAccess for PyDateTime {
/// Bindings for `datetime.time` /// Bindings for `datetime.time`
pub struct PyTime(PyObject); pub struct PyTime(PyObject);
pyobject_native_type!(PyTime, PyDateTime_TimeType, PyTime_Check); pyobject_native_type!(PyTime, *PyDateTimeAPI.TimeType, PyTime_Check);
impl PyTime { impl PyTime {
pub fn new( pub fn new(
@ -284,11 +280,11 @@ impl PyTimeAccess for PyTime {
/// ///
/// This is an abstract base class and should not be constructed directly. /// This is an abstract base class and should not be constructed directly.
pub struct PyTzInfo(PyObject); pub struct PyTzInfo(PyObject);
pyobject_native_type!(PyTzInfo, PyDateTime_TZInfoType, PyTZInfo_Check); pyobject_native_type!(PyTzInfo, *PyDateTimeAPI.TZInfoType, PyTZInfo_Check);
/// Bindings for `datetime.timedelta` /// Bindings for `datetime.timedelta`
pub struct PyDelta(PyObject); pub struct PyDelta(PyObject);
pyobject_native_type!(PyDelta, PyDateTime_DeltaType, PyDelta_Check); pyobject_native_type!(PyDelta, *PyDateTimeAPI.DeltaType, PyDelta_Check);
impl PyDelta { impl PyDelta {
pub fn new( pub fn new(