From 26fa0ddd094997b2305e31c145917a25dee725b5 Mon Sep 17 00:00:00 2001 From: zaur <aintellimath@gmail.com> Date: Wed, 27 Feb 2013 12:46:26 +0300 Subject: [PATCH] Add datetime.pxd to cython.cpython. Part II --- Cython/Includes/cpython/__init__.pxd | 2 + Cython/Includes/cpython/datetime.pxd | 206 +++++++++++++++++++++++++++ tests/run/datetime_cimport.pyx | 43 ++++++ tests/run/datetime_pxd.pyx | 173 ++++++++++++++++++++++ 4 files changed, 424 insertions(+) create mode 100644 Cython/Includes/cpython/datetime.pxd create mode 100644 tests/run/datetime_cimport.pyx create mode 100644 tests/run/datetime_pxd.pyx diff --git a/Cython/Includes/cpython/__init__.pxd b/Cython/Includes/cpython/__init__.pxd index 27c11604d..22b928e6d 100644 --- a/Cython/Includes/cpython/__init__.pxd +++ b/Cython/Includes/cpython/__init__.pxd @@ -182,3 +182,5 @@ from cpython.pycapsule cimport * ################################################################# # END OF DEPRECATED SECTION ################################################################# + +from cpython.datetime cimport * diff --git a/Cython/Includes/cpython/datetime.pxd b/Cython/Includes/cpython/datetime.pxd new file mode 100644 index 000000000..913d86414 --- /dev/null +++ b/Cython/Includes/cpython/datetime.pxd @@ -0,0 +1,206 @@ +from cpython.ref cimport PyObject + +cdef extern from "Python.h": + ctypedef struct PyTypeObject: + pass + +cdef extern from "datetime.h": + + ctypedef extern class datetime.date[object PyDateTime_Date]: + pass + + ctypedef extern class datetime.time[object PyDateTime_Time]: + pass + + ctypedef extern class datetime.datetime[object PyDateTime_DateTime]: + pass + + ctypedef extern class datetime.timedelta[object PyDateTime_Delta]: + pass + + ctypedef extern class datetime.tzinfo[object PyDateTime_TZInfo]: + pass + + ctypedef struct PyDateTime_Date: + pass + + ctypedef struct PyDateTime_Time: + char hastzinfo # boolean flag + PyObject *tzinfo + + ctypedef struct PyDateTime_DateTime: + char hastzinfo # boolean flag + PyObject *tzinfo + + # Define structure for C API. + ctypedef struct PyDateTime_CAPI: + long hashcode + # type objects + PyTypeObject *DateType + PyTypeObject *DateTimeType + PyTypeObject *TimeType + PyTypeObject *DeltaType + PyTypeObject *TZInfoType + + # constructors + object (*Date_FromDate)(int, int, int, PyTypeObject*) + object (*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, object, PyTypeObject*) + object (*Time_FromTime)(int, int, int, int, object, PyTypeObject*) + object (*Delta_FromDelta)(int, int, int, int, PyTypeObject*) + + # constructors for the DB API + object (*DateTime_FromTimestamp)(object, object, object) + object (*Date_FromTimestamp)(object, object) + + # Check type of the object. + bint PyDate_Check(object op) + bint PyDate_CheckExact(object op) + + bint PyDateTime_Check(object op) + bint PyDateTime_CheckExact(object op) + + bint PyTime_Check(object op) + bint PyTime_CheckExact(object op) + + bint PyDelta_Check(object op) + bint PyDelta_CheckExact(object op) + + bint PyTZInfo_Check(object op) + bint PyTZInfo_CheckExact(object op) + + # Getters for date and datetime (C macros). + int PyDateTime_GET_YEAR(object o) + int PyDateTime_GET_MONTH(object o) + int PyDateTime_GET_DAY(object o) + + # Getters for datetime (C macros). + int PyDateTime_DATE_GET_HOUR(object o) + int PyDateTime_DATE_GET_MINUTE(object o) + int PyDateTime_DATE_GET_SECOND(object o) + int PyDateTime_DATE_GET_MICROSECOND(object o) + + # Getters for time (C macros). + int PyDateTime_TIME_GET_HOUR(object o) + int PyDateTime_TIME_GET_MINUTE(object o) + int PyDateTime_TIME_GET_SECOND(object o) + int PyDateTime_TIME_GET_MICROSECOND(object o) + + # Getters for timedelta (C macros). + int PyDateTime_DELTA_GET_DAYS(object o) + int PyDateTime_DELTA_GET_SECONDS(object o) + int PyDateTime_DELTA_GET_MICROSECONDS(object o) + + # PyDateTime CAPI object. + PyDateTime_CAPI *PyDateTimeAPI + + # Datetime C API object initialization C macros. + # You have to call this before any usage of DateTime CAPI functions: + # PyDateTime_IMPORT + void PyDateTime_IMPORT() + +# Create date object using DateTime CAPI factory function. +# Note, there are no range checks for any of the arguments. +cdef inline object date_new(int year, int month, int day): + return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) + +# Create time object using DateTime CAPI factory function +# Note, there are no range checks for any of the arguments. +cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): + return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) + +# Create datetime object using DateTime CAPI factory function. +# Note, there are no range checks for any of the arguments. +cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): + return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) + +# Create timedelta object using DateTime CAPI factory function. +# Note, there are no range checks for any of the arguments. +cdef inline object timedelta_new(int days, int seconds, int useconds): + return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) + +# +# More recognizable getters for date/time/datetime/timedelta. +# There are no setters because datetime.h didn't exposed them. +# + +# Get tzinfo of time +cdef inline object time_tzinfo(object o): + if (<PyDateTime_Time*>o).hastzinfo: + return <object>(<PyDateTime_Time*>o).tzinfo + else: + return None + +# Get tzinfo of datetime +cdef inline object datetime_tzinfo(object o): + if (<PyDateTime_DateTime*>o).hastzinfo: + return <object>(<PyDateTime_DateTime*>o).tzinfo + else: + return None + +# Get year of date +cdef inline int date_year(object o): + return PyDateTime_GET_YEAR(o) + +# Get month of date +cdef inline int date_month(object o): + return PyDateTime_GET_MONTH(o) + +# Get day of date +cdef inline int date_day(object o): + return PyDateTime_GET_DAY(o) + +# Get year of datetime +cdef inline int datetime_year(object o): + return PyDateTime_GET_YEAR(o) + +# Get month of datetime +cdef inline int datetime_month(object o): + return PyDateTime_GET_MONTH(o) + +# Get day of datetime +cdef inline int datetime_day(object o): + return PyDateTime_GET_DAY(o) + +# Get hour of time +cdef inline int time_hour(object o): + return PyDateTime_TIME_GET_HOUR(o) + +# Get minute of time +cdef inline int time_minute(object o): + return PyDateTime_TIME_GET_MINUTE(o) + +# Get second of time +cdef inline int time_second(object o): + return PyDateTime_TIME_GET_SECOND(o) + +# Get microsecond of time +cdef inline int time_microsecond(object o): + return PyDateTime_TIME_GET_MICROSECOND(o) + +# Get hour of datetime +cdef inline int datetime_hour(object o): + return PyDateTime_DATE_GET_HOUR(o) + +# Get minute of datetime +cdef inline int datetime_minute(object o): + return PyDateTime_DATE_GET_MINUTE(o) + +# Get second of datetime +cdef inline int datetime_second(object o): + return PyDateTime_DATE_GET_SECOND(o) + +# Get microsecond of datetime +cdef inline int datetime_microsecond(object o): + return PyDateTime_DATE_GET_MICROSECOND(o) + +# Get days of timedelta +cdef inline int timedelta_days(object o): + return PyDateTime_DELTA_GET_DAYS(o) + +# Get seconds of timedelta +cdef inline int timedelta_seconds(object o): + return PyDateTime_DELTA_GET_SECONDS(o) + +# Get microseconds of timedelta +cdef inline int timedelta_microseconds(object o): + return PyDateTime_DELTA_GET_MICROSECONDS(o) diff --git a/tests/run/datetime_cimport.pyx b/tests/run/datetime_cimport.pyx new file mode 100644 index 000000000..af3efd932 --- /dev/null +++ b/tests/run/datetime_cimport.pyx @@ -0,0 +1,43 @@ +# coding: utf-8 + +#import datetime +from cpython.datetime cimport date, time, datetime, timedelta, PyDateTime_IMPORT + +PyDateTime_IMPORT + +def test_date(int year, int month, int day): + ''' + >>> val = test_date(2012, 12, 31) + >>> print(val) + 2012-12-31 + ''' + val = date(year, month, day) + return val + +def test_time(int hour, int minute, int second, int microsecond): + ''' + >>> val = test_time(12, 20, 55, 0) + >>> print(val) + 12:20:55 + ''' + val = time(hour, minute, second, microsecond) + return val + +def test_datetime(int year, int month, int day, int hour, int minute, int second, int microsecond): + ''' + >>> val = test_datetime(2012, 12, 31, 12, 20, 55, 0) + >>> print(val) + 2012-12-31 12:20:55 + ''' + val = datetime(year, month, day, hour, minute, second, microsecond) + return val + +def test_timedelta(int days, int seconds, int useconds): + ''' + >>> val = test_timedelta(30, 0, 0) + >>> print(val) + 30 days, 0:00:00 + ''' + val = timedelta(days, seconds, useconds) + return val + \ No newline at end of file diff --git a/tests/run/datetime_pxd.pyx b/tests/run/datetime_pxd.pyx new file mode 100644 index 000000000..99b7937db --- /dev/null +++ b/tests/run/datetime_pxd.pyx @@ -0,0 +1,173 @@ +# coding: utf-8 + +#cimport cpython.datetime as cy_datetime +#from datetime import time, date, datetime, timedelta, tzinfo + + +from cpython.datetime cimport PyDateTime_IMPORT +from cpython.datetime cimport time_new, date_new, datetime_new, timedelta_new +from cpython.datetime cimport time_tzinfo, datetime_tzinfo +from cpython.datetime cimport time_hour, time_minute, time_second, time_microsecond +from cpython.datetime cimport date_day, date_month, date_year +from cpython.datetime cimport datetime_day, datetime_month, datetime_year +from cpython.datetime cimport datetime_hour, datetime_minute, datetime_second, \ + datetime_microsecond + +import datetime as py_datetime + +PyDateTime_IMPORT + +ZERO = py_datetime.timedelta(0) + +# +# Simple class from datetime docs +# +class FixedOffset(py_datetime.tzinfo): + """Fixed offset in minutes east from UTC.""" + + def __init__(self, offset, name): + self._offset = py_datetime.timedelta(minutes = offset) + self._name = name + + def utcoffset(self, dt): + return self._offset + + def tzname(self, dt): + return self._name + + def dst(self, dt): + return ZERO + +def do_date(int year, int month, int day): + """ + >>> do_date(2012, 12, 31) + (True, True, True, True) + """ + v = date_new(year, month, day) + return type(v) is py_datetime.date, v.year == year, v.month == month, v.day == day + +def do_datetime(int year, int month, int day, + int hour, int minute, int second, int microsecond): + """ + >>> do_datetime(2012, 12, 31, 12, 23, 0, 0) + (True, True, True, True, True, True, True, True, True) + """ + v = datetime_new(year, month, day, hour, minute, second, microsecond, None) + return type(v) is py_datetime.datetime, v.year == year, v.month == month, v.day == day, \ + v.hour == hour, v.minute == minute, v.second == second, \ + v.microsecond == microsecond, v.tzinfo is None + +def do_time(int hour, int minute, int second, int microsecond): + """ + >>> do_time(12, 23, 0, 0) + (True, True, True, True, True, True) + """ + v = time_new(hour, minute, second, microsecond, None) + return type(v) is py_datetime.time, \ + v.hour == hour, v.minute == minute, v.second == second, \ + v.microsecond == microsecond, v.tzinfo is None + +def do_time_tzinfo(int hour, int minute, int second, int microsecond, object tz): + """ + >>> tz = FixedOffset(60*3, 'Moscow') + >>> do_time_tzinfo(12, 23, 0, 0, tz) + (True, True, True, True, True, True) + """ + v = time_new(hour, minute, second, microsecond, tz) + return type(v) is py_datetime.time, \ + v.hour == hour, v.minute == minute, v.second == second, \ + v.microsecond == microsecond, v.tzinfo is tz + + +def do_datetime_tzinfo(int year, int month, int day, + int hour, int minute, int second, int microsecond, object tz): + """ + >>> tz = FixedOffset(60*3, 'Moscow') + >>> do_datetime_tzinfo(2012, 12, 31, 12, 23, 0, 0, tz) + (True, True, True, True, True, True, True, True, True) + """ + v = datetime_new(year, month, day, hour, minute, second, microsecond, tz) + return type(v) is py_datetime.datetime, v.year == year, v.month == month, v.day == day, \ + v.hour == hour, v.minute == minute, v.second == second, \ + v.microsecond == microsecond, v.tzinfo is tz + +def do_time_tzinfo2(int hour, int minute, int second, int microsecond, object tz): + """ + >>> tz = FixedOffset(60*3, 'Moscow') + >>> do_time_tzinfo2(12, 23, 0, 0, tz) + (True, True, True, True, True, True, True, True) + """ + v = time_new(hour, minute, second, microsecond, None) + v1 = time_new( + time_hour(v), + time_minute(v), + time_second(v), + time_microsecond(v), + tz) + r1 = (v1.tzinfo == tz) + r2 = (tz == time_tzinfo(v1)) + v2 = time_new( + time_hour(v1), + time_minute(v1), + time_second(v1), + time_microsecond(v1), + None) + r3 = (v2.tzinfo == None) + r4 = (None == time_tzinfo(v2)) + v3 = time_new( + time_hour(v2), + time_minute(v2), + time_second(v2), + time_microsecond(v2), + tz) + r5 = (v3.tzinfo == tz) + r6 = (tz == time_tzinfo(v3)) + r7 = (v2 == v) + r8 = (v3 == v1) + return r1, r2, r3, r4, r5, r6, r7, r8 + + +def do_datetime_tzinfo2(int year, int month, int day, + int hour, int minute, int second, int microsecond, object tz): + """ + >>> tz = FixedOffset(60*3, 'Moscow') + >>> do_datetime_tzinfo2(2012, 12, 31, 12, 23, 0, 0, tz) + (True, True, True, True, True, True, True, True) + """ + v = datetime_new(year, month, day, hour, minute, second, microsecond, None) + v1 = datetime_new( + datetime_year(v), + datetime_month(v), + datetime_day(v), + datetime_hour(v), + datetime_minute(v), + datetime_second(v), + datetime_microsecond(v), + tz) + r1 = (v1.tzinfo == tz) + r2 = (tz == datetime_tzinfo(v1)) + v2 = datetime_new( + datetime_year(v1), + datetime_month(v1), + datetime_day(v1), + datetime_hour(v1), + datetime_minute(v1), + datetime_second(v1), + datetime_microsecond(v1), + None) + r3 = (v2.tzinfo == None) + r4 = (None == datetime_tzinfo(v2)) + v3 = datetime_new( + datetime_year(v2), + datetime_month(v2), + datetime_day(v2), + datetime_hour(v2), + datetime_minute(v2), + datetime_second(v2), + datetime_microsecond(v2), + tz) + r5 = (v3.tzinfo == tz) + r6 = (tz == datetime_tzinfo(v3)) + r7 = (v2 == v) + r8 = (v3 == v1) + return r1, r2, r3, r4, r5, r6, r7, r8 -- 2.30.9