Spaces:
Build error
Build error
from cpython.object cimport PyObject | |
from cpython.version cimport PY_VERSION_HEX | |
cdef extern from "Python.h": | |
ctypedef struct PyTypeObject: | |
pass | |
cdef extern from "datetime.h": | |
""" | |
/* Backport for Python 2.x */ | |
#if PY_MAJOR_VERSION < 3 | |
#ifndef PyDateTime_DELTA_GET_DAYS | |
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) | |
#endif | |
#ifndef PyDateTime_DELTA_GET_SECONDS | |
#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) | |
#endif | |
#ifndef PyDateTime_DELTA_GET_MICROSECONDS | |
#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) | |
#endif | |
#endif | |
/* Backport for Python < 3.6 */ | |
#if PY_VERSION_HEX < 0x030600a4 | |
#ifndef PyDateTime_TIME_GET_FOLD | |
#define PyDateTime_TIME_GET_FOLD(o) ((void)(o), 0) | |
#endif | |
#ifndef PyDateTime_DATE_GET_FOLD | |
#define PyDateTime_DATE_GET_FOLD(o) ((void)(o), 0) | |
#endif | |
#endif | |
/* Backport for Python < 3.6 */ | |
#if PY_VERSION_HEX < 0x030600a4 | |
#define __Pyx_DateTime_DateTimeWithFold(year, month, day, hour, minute, second, microsecond, tz, fold) \ | |
((void)(fold), PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, minute, second, \ | |
microsecond, tz, PyDateTimeAPI->DateTimeType)) | |
#define __Pyx_DateTime_TimeWithFold(hour, minute, second, microsecond, tz, fold) \ | |
((void)(fold), PyDateTimeAPI->Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI->TimeType)) | |
#else /* For Python 3.6+ so that we can pass tz */ | |
#define __Pyx_DateTime_DateTimeWithFold(year, month, day, hour, minute, second, microsecond, tz, fold) \ | |
PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, minute, second, \ | |
microsecond, tz, fold, PyDateTimeAPI->DateTimeType) | |
#define __Pyx_DateTime_TimeWithFold(hour, minute, second, microsecond, tz, fold) \ | |
PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, microsecond, tz, fold, PyDateTimeAPI->TimeType) | |
#endif | |
/* Backport for Python < 3.7 */ | |
#if PY_VERSION_HEX < 0x030700b1 | |
#define __Pyx_TimeZone_UTC NULL | |
#define __Pyx_TimeZone_FromOffsetAndName(offset, name) ((void)(offset), (void)(name), (PyObject*)NULL) | |
#else | |
#define __Pyx_TimeZone_UTC PyDateTime_TimeZone_UTC | |
#define __Pyx_TimeZone_FromOffsetAndName(offset, name) PyTimeZone_FromOffsetAndName(offset, name) | |
#endif | |
/* Backport for Python < 3.10 */ | |
#if PY_VERSION_HEX < 0x030a00a1 | |
#ifndef PyDateTime_TIME_GET_TZINFO | |
#define PyDateTime_TIME_GET_TZINFO(o) \ | |
((((PyDateTime_Time*)o)->hastzinfo) ? ((PyDateTime_Time*)o)->tzinfo : Py_None) | |
#endif | |
#ifndef PyDateTime_DATE_GET_TZINFO | |
#define PyDateTime_DATE_GET_TZINFO(o) \ | |
((((PyDateTime_DateTime*)o)->hastzinfo) ? ((PyDateTime_DateTime*)o)->tzinfo : Py_None) | |
#endif | |
#endif | |
""" | |
ctypedef extern class datetime.date[object PyDateTime_Date]: | |
@property | |
cdef inline int year(self) noexcept: | |
return PyDateTime_GET_YEAR(self) | |
@property | |
cdef inline int month(self) noexcept: | |
return PyDateTime_GET_MONTH(self) | |
@property | |
cdef inline int day(self) noexcept: | |
return PyDateTime_GET_DAY(self) | |
ctypedef extern class datetime.time[object PyDateTime_Time]: | |
@property | |
cdef inline int hour(self) noexcept: | |
return PyDateTime_TIME_GET_HOUR(self) | |
@property | |
cdef inline int minute(self) noexcept: | |
return PyDateTime_TIME_GET_MINUTE(self) | |
@property | |
cdef inline int second(self) noexcept: | |
return PyDateTime_TIME_GET_SECOND(self) | |
@property | |
cdef inline int microsecond(self) noexcept: | |
return PyDateTime_TIME_GET_MICROSECOND(self) | |
@property | |
cdef inline object tzinfo(self): | |
return <object>PyDateTime_TIME_GET_TZINFO(self) | |
@property | |
cdef inline int fold(self) noexcept: | |
# For Python < 3.6 this returns 0 no matter what | |
return PyDateTime_TIME_GET_FOLD(self) | |
ctypedef extern class datetime.datetime[object PyDateTime_DateTime]: | |
@property | |
cdef inline int year(self) noexcept: | |
return PyDateTime_GET_YEAR(self) | |
@property | |
cdef inline int month(self) noexcept: | |
return PyDateTime_GET_MONTH(self) | |
@property | |
cdef inline int day(self) noexcept: | |
return PyDateTime_GET_DAY(self) | |
@property | |
cdef inline int hour(self) noexcept: | |
return PyDateTime_DATE_GET_HOUR(self) | |
@property | |
cdef inline int minute(self) noexcept: | |
return PyDateTime_DATE_GET_MINUTE(self) | |
@property | |
cdef inline int second(self) noexcept: | |
return PyDateTime_DATE_GET_SECOND(self) | |
@property | |
cdef inline int microsecond(self) noexcept: | |
return PyDateTime_DATE_GET_MICROSECOND(self) | |
@property | |
cdef inline object tzinfo(self): | |
return <object>PyDateTime_DATE_GET_TZINFO(self) | |
@property | |
cdef inline int fold(self) noexcept: | |
# For Python < 3.6 this returns 0 no matter what | |
return PyDateTime_DATE_GET_FOLD(self) | |
ctypedef extern class datetime.timedelta[object PyDateTime_Delta]: | |
@property | |
cdef inline int day(self) noexcept: | |
return PyDateTime_DELTA_GET_DAYS(self) | |
@property | |
cdef inline int second(self) noexcept: | |
return PyDateTime_DELTA_GET_SECONDS(self) | |
@property | |
cdef inline int microsecond(self) noexcept: | |
return PyDateTime_DELTA_GET_MICROSECONDS(self) | |
ctypedef extern class datetime.tzinfo[object PyDateTime_TZInfo]: | |
pass | |
ctypedef struct PyDateTime_Date: | |
pass | |
ctypedef struct PyDateTime_Time: | |
unsigned char fold | |
char hastzinfo | |
PyObject *tzinfo | |
ctypedef struct PyDateTime_DateTime: | |
unsigned char fold | |
char hastzinfo | |
PyObject *tzinfo | |
ctypedef struct PyDateTime_Delta: | |
int days | |
int seconds | |
int microseconds | |
# Define structure for C API. | |
ctypedef struct PyDateTime_CAPI: | |
# type objects | |
PyTypeObject *DateType | |
PyTypeObject *DateTimeType | |
PyTypeObject *TimeType | |
PyTypeObject *DeltaType | |
PyTypeObject *TZInfoType | |
# constructors | |
date (*Date_FromDate)(int, int, int, PyTypeObject*) | |
datetime (*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, object, PyTypeObject*) | |
time (*Time_FromTime)(int, int, int, int, object, PyTypeObject*) | |
timedelta (*Delta_FromDelta)(int, int, int, int, PyTypeObject*) | |
# constructors for the DB API | |
datetime (*DateTime_FromTimestamp)(PyObject*, object, PyObject*) | |
date (*Date_FromTimestamp)(PyObject*, object) | |
# We cannot use the following because they do not compile in older Python versions. | |
# Instead, we use datetime.h's macros here that we can backport in C. | |
# Python 3.7+ constructors | |
object (*TimeZone_FromTimeZone)(object offset, PyObject *name) | |
# Python 3.7+ singletons | |
PyObject *TimeZone_UTC | |
# Python 3.6+ PEP 495 constructors | |
datetime (*DateTime_FromDateAndTimeAndFold)(int, int, int, int, int, int, int, object, int, PyTypeObject*) | |
time (*Time_FromTimeAndFold)(int, int, int ,int, object, int, PyTypeObject*) | |
# 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) | |
int PyDateTime_DATE_GET_FOLD(object o) | |
PyObject* PyDateTime_DATE_GET_TZINFO(object o) # returns a borrowed reference | |
# 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) | |
int PyDateTime_TIME_GET_FOLD(object o) | |
PyObject* PyDateTime_TIME_GET_TZINFO(object o) # returns a borrowed reference | |
# 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) | |
# Constructors | |
object PyTimeZone_FromOffset(object offset) | |
object PyTimeZone_FromOffsetAndName(object offset, object name) | |
# The above macros is Python 3.7+ so we use these instead | |
object __Pyx_TimeZone_FromOffsetAndName(object offset, PyObject* name) | |
# Constructors for the DB API | |
datetime PyDateTime_FromTimeStamp(object args) | |
date PyDate_FromTimeStamp(object args) | |
# PEP 495 constructors but patched above to allow passing tz | |
datetime __Pyx_DateTime_DateTimeWithFold(int, int, int, int, int, int, int, object, int) | |
datetime __Pyx_DateTime_TimeWithFold(int, int, int ,int, object, int) | |
# PyDateTime CAPI object. | |
PyDateTime_CAPI *PyDateTimeAPI | |
PyObject* PyDateTime_TimeZone_UTC | |
# PyDateTime_TimeZone_UTC is Python 3.7+ so instead we use the following macro | |
PyObject* __Pyx_TimeZone_UTC | |
void PyDateTime_IMPORT() | |
# Datetime C API initialization function. | |
# You have to call it before any usage of DateTime CAPI functions. | |
cdef inline void import_datetime() noexcept: | |
PyDateTime_IMPORT | |
# Create date object using DateTime CAPI factory function. | |
# Note, there are no range checks for any of the arguments. | |
cdef inline date 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 time time_new(int hour, int minute, int second, int microsecond, object tz, int fold=0): | |
return __Pyx_DateTime_TimeWithFold(hour, minute, second, microsecond, tz, fold) | |
# Create datetime object using DateTime CAPI factory function. | |
# Note, there are no range checks for any of the arguments. | |
cdef inline datetime datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz, int fold=0): | |
return __Pyx_DateTime_DateTimeWithFold(year, month, day, hour, minute, second, microsecond, tz, fold) | |
# Create timedelta object using DateTime CAPI factory function. | |
# Note, there are no range checks for any of the arguments. | |
cdef inline timedelta timedelta_new(int days, int seconds, int useconds): | |
return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) | |
# Create timedelta object using DateTime CAPI factory function. | |
cdef inline object timezone_new(object offset, object name=None): | |
if PY_VERSION_HEX < 0x030700b1: | |
raise RuntimeError('Time zones are not available from the C-API.') | |
return __Pyx_TimeZone_FromOffsetAndName(offset, <PyObject*>name if name is not None else NULL) | |
# Create datetime object using DB API constructor. | |
cdef inline datetime datetime_from_timestamp(timestamp, tz=None): | |
return PyDateTimeAPI.DateTime_FromTimestamp( | |
<PyObject*>PyDateTimeAPI.DateTimeType, (timestamp, tz) if tz is not None else (timestamp,), NULL) | |
# Create date object using DB API constructor. | |
cdef inline date date_from_timestamp(timestamp): | |
return PyDateTimeAPI.Date_FromTimestamp(<PyObject*>PyDateTimeAPI.DateType, (timestamp,)) | |
# More recognizable getters for date/time/datetime/timedelta. | |
# There are no setters because datetime.h hasn't them. | |
# This is because of immutable nature of these objects by design. | |
# If you would change time/date/datetime/timedelta object you need to recreate. | |
# Get UTC singleton | |
cdef inline object get_utc(): | |
if PY_VERSION_HEX < 0x030700b1: | |
raise RuntimeError('Time zones are not available from the C-API.') | |
return <object>__Pyx_TimeZone_UTC | |
# Get tzinfo of time | |
cdef inline object time_tzinfo(object o): | |
return <object>PyDateTime_TIME_GET_TZINFO(o) | |
# Get tzinfo of datetime | |
cdef inline object datetime_tzinfo(object o): | |
return <object>PyDateTime_DATE_GET_TZINFO(o) | |
# Get year of date | |
cdef inline int date_year(object o) noexcept: | |
return PyDateTime_GET_YEAR(o) | |
# Get month of date | |
cdef inline int date_month(object o) noexcept: | |
return PyDateTime_GET_MONTH(o) | |
# Get day of date | |
cdef inline int date_day(object o) noexcept: | |
return PyDateTime_GET_DAY(o) | |
# Get year of datetime | |
cdef inline int datetime_year(object o) noexcept: | |
return PyDateTime_GET_YEAR(o) | |
# Get month of datetime | |
cdef inline int datetime_month(object o) noexcept: | |
return PyDateTime_GET_MONTH(o) | |
# Get day of datetime | |
cdef inline int datetime_day(object o) noexcept: | |
return PyDateTime_GET_DAY(o) | |
# Get hour of time | |
cdef inline int time_hour(object o) noexcept: | |
return PyDateTime_TIME_GET_HOUR(o) | |
# Get minute of time | |
cdef inline int time_minute(object o) noexcept: | |
return PyDateTime_TIME_GET_MINUTE(o) | |
# Get second of time | |
cdef inline int time_second(object o) noexcept: | |
return PyDateTime_TIME_GET_SECOND(o) | |
# Get microsecond of time | |
cdef inline int time_microsecond(object o) noexcept: | |
return PyDateTime_TIME_GET_MICROSECOND(o) | |
# Get fold of time | |
cdef inline int time_fold(object o) noexcept: | |
# For Python < 3.6 this returns 0 no matter what | |
return PyDateTime_TIME_GET_FOLD(o) | |
# Get hour of datetime | |
cdef inline int datetime_hour(object o) noexcept: | |
return PyDateTime_DATE_GET_HOUR(o) | |
# Get minute of datetime | |
cdef inline int datetime_minute(object o) noexcept: | |
return PyDateTime_DATE_GET_MINUTE(o) | |
# Get second of datetime | |
cdef inline int datetime_second(object o) noexcept: | |
return PyDateTime_DATE_GET_SECOND(o) | |
# Get microsecond of datetime | |
cdef inline int datetime_microsecond(object o) noexcept: | |
return PyDateTime_DATE_GET_MICROSECOND(o) | |
# Get fold of datetime | |
cdef inline int datetime_fold(object o) noexcept: | |
# For Python < 3.6 this returns 0 no matter what | |
return PyDateTime_DATE_GET_FOLD(o) | |
# Get days of timedelta | |
cdef inline int timedelta_days(object o) noexcept: | |
return (<PyDateTime_Delta*>o).days | |
# Get seconds of timedelta | |
cdef inline int timedelta_seconds(object o) noexcept: | |
return (<PyDateTime_Delta*>o).seconds | |
# Get microseconds of timedelta | |
cdef inline int timedelta_microseconds(object o) noexcept: | |
return (<PyDateTime_Delta*>o).microseconds | |
cdef inline double total_seconds(timedelta obj) noexcept: | |
# Mirrors the "timedelta.total_seconds()" method. | |
# Note that this implementation is not guaranteed to give *exactly* the same | |
# result as the original method, due to potential differences in floating point rounding. | |
cdef: | |
double days, seconds, micros | |
days = <double>PyDateTime_DELTA_GET_DAYS(obj) | |
seconds = <double>PyDateTime_DELTA_GET_SECONDS(obj) | |
micros = <double>PyDateTime_DELTA_GET_MICROSECONDS(obj) | |
return days * 24 * 3600 + seconds + micros / 1_000_000 | |