Spaces:
Build error
Build error
File size: 15,793 Bytes
64772a4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
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
|