| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | #include "parts.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "datetime.h"             // PyDateTimeAPI
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_run_counter = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | test_datetime_capi(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (PyDateTimeAPI) { | 
					
						
							|  |  |  |         if (test_run_counter) { | 
					
						
							|  |  |  |             /* Probably regrtest.py -R */ | 
					
						
							|  |  |  |             Py_RETURN_NONE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_AssertionError, | 
					
						
							|  |  |  |                             "PyDateTime_CAPI somehow initialized"); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     test_run_counter++; | 
					
						
							|  |  |  |     PyDateTime_IMPORT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-14 03:05:03 +09:00
										 |  |  |     if (PyDateTimeAPI == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-06-14 03:05:03 +09:00
										 |  |  |     // The following C API types need to outlive interpreters, since the
 | 
					
						
							|  |  |  |     // borrowed references to them can be held by users without being updated.
 | 
					
						
							|  |  |  |     assert(!PyType_HasFeature(PyDateTimeAPI->DateType, Py_TPFLAGS_HEAPTYPE)); | 
					
						
							|  |  |  |     assert(!PyType_HasFeature(PyDateTimeAPI->TimeType, Py_TPFLAGS_HEAPTYPE)); | 
					
						
							|  |  |  |     assert(!PyType_HasFeature(PyDateTimeAPI->DateTimeType, Py_TPFLAGS_HEAPTYPE)); | 
					
						
							|  |  |  |     assert(!PyType_HasFeature(PyDateTimeAPI->DeltaType, Py_TPFLAGS_HEAPTYPE)); | 
					
						
							|  |  |  |     assert(!PyType_HasFeature(PyDateTimeAPI->TZInfoType, Py_TPFLAGS_HEAPTYPE)); | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Functions exposing the C API type checking for testing */ | 
					
						
							|  |  |  | #define MAKE_DATETIME_CHECK_FUNC(check_method, exact_method)    \
 | 
					
						
							|  |  |  | do {                                                            \ | 
					
						
							|  |  |  |     PyObject *obj;                                              \ | 
					
						
							|  |  |  |     int exact = 0;                                              \ | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "O|p", &obj, &exact)) {         \ | 
					
						
							|  |  |  |         return NULL;                                            \ | 
					
						
							|  |  |  |     }                                                           \ | 
					
						
							|  |  |  |     int rv = exact?exact_method(obj):check_method(obj);         \ | 
					
						
							|  |  |  |     if (rv) {                                                   \ | 
					
						
							|  |  |  |         Py_RETURN_TRUE;                                         \ | 
					
						
							|  |  |  |     }                                                           \ | 
					
						
							|  |  |  |     Py_RETURN_FALSE;                                            \ | 
					
						
							|  |  |  | } while (0)                                                     \ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | datetime_check_date(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MAKE_DATETIME_CHECK_FUNC(PyDate_Check, PyDate_CheckExact); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | datetime_check_time(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MAKE_DATETIME_CHECK_FUNC(PyTime_Check, PyTime_CheckExact); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | datetime_check_datetime(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MAKE_DATETIME_CHECK_FUNC(PyDateTime_Check, PyDateTime_CheckExact); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | datetime_check_delta(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MAKE_DATETIME_CHECK_FUNC(PyDelta_Check, PyDelta_CheckExact); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | datetime_check_tzinfo(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MAKE_DATETIME_CHECK_FUNC(PyTZInfo_Check, PyTZInfo_CheckExact); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #undef MAKE_DATETIME_CHECK_FUNC
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Makes three variations on timezone representing UTC-5:
 | 
					
						
							|  |  |  |    1. timezone with offset and name from PyDateTimeAPI | 
					
						
							|  |  |  |    2. timezone with offset and name from PyTimeZone_FromOffsetAndName | 
					
						
							|  |  |  |    3. timezone with offset (no name) from PyTimeZone_FromOffset | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | make_timezones_capi(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *offset = PyDelta_FromDSU(0, -18000, 0); | 
					
						
							|  |  |  |     PyObject *name = PyUnicode_FromString("EST"); | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  |     if (offset == NULL || name == NULL) { | 
					
						
							|  |  |  |         Py_XDECREF(offset); | 
					
						
							|  |  |  |         Py_XDECREF(name); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyObject *est_zone_capi = PyDateTimeAPI->TimeZone_FromTimeZone(offset, name); | 
					
						
							|  |  |  |     PyObject *est_zone_macro = PyTimeZone_FromOffsetAndName(offset, name); | 
					
						
							|  |  |  |     PyObject *est_zone_macro_noname = PyTimeZone_FromOffset(offset); | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  |     Py_DECREF(offset); | 
					
						
							|  |  |  |     Py_DECREF(name); | 
					
						
							|  |  |  |     if (est_zone_capi == NULL || est_zone_macro == NULL || | 
					
						
							|  |  |  |         est_zone_macro_noname == NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  |     PyObject *rv = PyTuple_New(3); | 
					
						
							|  |  |  |     if (rv == NULL) { | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  |         goto error; | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(rv, 0, est_zone_capi); | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(rv, 1, est_zone_macro); | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(rv, 2, est_zone_macro_noname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return rv; | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  | error: | 
					
						
							|  |  |  |     Py_XDECREF(est_zone_capi); | 
					
						
							|  |  |  |     Py_XDECREF(est_zone_macro); | 
					
						
							|  |  |  |     Py_XDECREF(est_zone_macro_noname); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_timezones_offset_zero(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *offset = PyDelta_FromDSU(0, 0, 0); | 
					
						
							| 
									
										
										
										
											2024-10-09 17:15:23 +02:00
										 |  |  |     PyObject *name = Py_GetConstant(Py_CONSTANT_EMPTY_STR); | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  |     if (offset == NULL || name == NULL) { | 
					
						
							|  |  |  |         Py_XDECREF(offset); | 
					
						
							|  |  |  |         Py_XDECREF(name); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // These two should return the UTC singleton
 | 
					
						
							|  |  |  |     PyObject *utc_singleton_0 = PyTimeZone_FromOffset(offset); | 
					
						
							|  |  |  |     PyObject *utc_singleton_1 = PyTimeZone_FromOffsetAndName(offset, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // This one will return +00:00 zone, but not the UTC singleton
 | 
					
						
							|  |  |  |     PyObject *non_utc_zone = PyTimeZone_FromOffsetAndName(offset, name); | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  |     Py_DECREF(offset); | 
					
						
							|  |  |  |     Py_DECREF(name); | 
					
						
							|  |  |  |     if (utc_singleton_0 == NULL || utc_singleton_1 == NULL || | 
					
						
							|  |  |  |         non_utc_zone == NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PyObject *rv = PyTuple_New(3); | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  |     if (rv == NULL) { | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  |     PyTuple_SET_ITEM(rv, 0, utc_singleton_0); | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(rv, 1, utc_singleton_1); | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(rv, 2, non_utc_zone); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return rv; | 
					
						
							| 
									
										
										
										
											2023-12-14 11:06:53 -08:00
										 |  |  | error: | 
					
						
							|  |  |  |     Py_XDECREF(utc_singleton_0); | 
					
						
							|  |  |  |     Py_XDECREF(utc_singleton_1); | 
					
						
							|  |  |  |     Py_XDECREF(non_utc_zone); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_timezone_utc_capi(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int macro = 0; | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "|p", ¯o)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							| 
									
										
										
										
											2022-11-16 10:39:47 +01:00
										 |  |  |         return Py_NewRef(PyDateTime_TimeZone_UTC); | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-16 10:39:47 +01:00
										 |  |  |     return Py_NewRef(PyDateTimeAPI->TimeZone_UTC); | 
					
						
							| 
									
										
										
										
											2022-11-15 08:17:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_date_fromdate(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *rv = NULL; | 
					
						
							|  |  |  |     int macro; | 
					
						
							|  |  |  |     int year, month, day; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyDate_FromDate(year, month, day); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->Date_FromDate( | 
					
						
							|  |  |  |                 year, month, day, | 
					
						
							|  |  |  |                 PyDateTimeAPI->DateType); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_datetime_fromdateandtime(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *rv = NULL; | 
					
						
							|  |  |  |     int macro; | 
					
						
							|  |  |  |     int year, month, day; | 
					
						
							|  |  |  |     int hour, minute, second, microsecond; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "piiiiiii", | 
					
						
							|  |  |  |                           ¯o, | 
					
						
							|  |  |  |                           &year, &month, &day, | 
					
						
							|  |  |  |                           &hour, &minute, &second, µsecond)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyDateTime_FromDateAndTime( | 
					
						
							|  |  |  |                 year, month, day, | 
					
						
							|  |  |  |                 hour, minute, second, microsecond); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->DateTime_FromDateAndTime( | 
					
						
							|  |  |  |                 year, month, day, | 
					
						
							|  |  |  |                 hour, minute, second, microsecond, | 
					
						
							|  |  |  |                 Py_None, | 
					
						
							|  |  |  |                 PyDateTimeAPI->DateTimeType); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *rv = NULL; | 
					
						
							|  |  |  |     int macro; | 
					
						
							|  |  |  |     int year, month, day; | 
					
						
							|  |  |  |     int hour, minute, second, microsecond, fold; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "piiiiiiii", | 
					
						
							|  |  |  |                           ¯o, | 
					
						
							|  |  |  |                           &year, &month, &day, | 
					
						
							|  |  |  |                           &hour, &minute, &second, µsecond, | 
					
						
							|  |  |  |                           &fold)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyDateTime_FromDateAndTimeAndFold( | 
					
						
							|  |  |  |                 year, month, day, | 
					
						
							|  |  |  |                 hour, minute, second, microsecond, | 
					
						
							|  |  |  |                 fold); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold( | 
					
						
							|  |  |  |                 year, month, day, | 
					
						
							|  |  |  |                 hour, minute, second, microsecond, | 
					
						
							|  |  |  |                 Py_None, | 
					
						
							|  |  |  |                 fold, | 
					
						
							|  |  |  |                 PyDateTimeAPI->DateTimeType); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_time_fromtime(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *rv = NULL; | 
					
						
							|  |  |  |     int macro; | 
					
						
							|  |  |  |     int hour, minute, second, microsecond; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "piiii", | 
					
						
							|  |  |  |                           ¯o, | 
					
						
							|  |  |  |                           &hour, &minute, &second, µsecond)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyTime_FromTime(hour, minute, second, microsecond); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->Time_FromTime( | 
					
						
							|  |  |  |                 hour, minute, second, microsecond, | 
					
						
							|  |  |  |                 Py_None, | 
					
						
							|  |  |  |                 PyDateTimeAPI->TimeType); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_time_fromtimeandfold(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *rv = NULL; | 
					
						
							|  |  |  |     int macro; | 
					
						
							|  |  |  |     int hour, minute, second, microsecond, fold; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "piiiii", | 
					
						
							|  |  |  |                           ¯o, | 
					
						
							|  |  |  |                           &hour, &minute, &second, µsecond, | 
					
						
							|  |  |  |                           &fold)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->Time_FromTimeAndFold( | 
					
						
							|  |  |  |                 hour, minute, second, microsecond, | 
					
						
							|  |  |  |                 Py_None, | 
					
						
							|  |  |  |                 fold, | 
					
						
							|  |  |  |                 PyDateTimeAPI->TimeType); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_delta_fromdsu(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *rv = NULL; | 
					
						
							|  |  |  |     int macro; | 
					
						
							|  |  |  |     int days, seconds, microseconds; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "piii", | 
					
						
							|  |  |  |                           ¯o, | 
					
						
							|  |  |  |                           &days, &seconds, µseconds)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyDelta_FromDSU(days, seconds, microseconds); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->Delta_FromDelta( | 
					
						
							|  |  |  |                 days, seconds, microseconds, 1, | 
					
						
							|  |  |  |                 PyDateTimeAPI->DeltaType); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_date_fromtimestamp(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *tsargs = NULL, *ts = NULL, *rv = NULL; | 
					
						
							|  |  |  |     int macro = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Construct the argument tuple
 | 
					
						
							|  |  |  |     if ((tsargs = PyTuple_Pack(1, ts)) == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Pass along to the API function
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyDate_FromTimestamp(tsargs); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->Date_FromTimestamp( | 
					
						
							|  |  |  |                 (PyObject *)PyDateTimeAPI->DateType, tsargs | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(tsargs); | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | get_datetime_fromtimestamp(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int macro = 0; | 
					
						
							|  |  |  |     int usetz = 0; | 
					
						
							|  |  |  |     PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL; | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Construct the argument tuple
 | 
					
						
							|  |  |  |     if (usetz) { | 
					
						
							|  |  |  |         tsargs = PyTuple_Pack(2, ts, tzinfo); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         tsargs = PyTuple_Pack(1, ts); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tsargs == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Pass along to the API function
 | 
					
						
							|  |  |  |     if (macro) { | 
					
						
							|  |  |  |         rv = PyDateTime_FromTimestamp(tsargs); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         rv = PyDateTimeAPI->DateTime_FromTimestamp( | 
					
						
							|  |  |  |                 (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(tsargs); | 
					
						
							|  |  |  |     return rv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | test_PyDateTime_GET(PyObject *self, PyObject *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int year, month, day; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     year = PyDateTime_GET_YEAR(obj); | 
					
						
							|  |  |  |     month = PyDateTime_GET_MONTH(obj); | 
					
						
							|  |  |  |     day = PyDateTime_GET_DAY(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Py_BuildValue("(iii)", year, month, day); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int hour = PyDateTime_DATE_GET_HOUR(obj); | 
					
						
							|  |  |  |     int minute = PyDateTime_DATE_GET_MINUTE(obj); | 
					
						
							|  |  |  |     int second = PyDateTime_DATE_GET_SECOND(obj); | 
					
						
							|  |  |  |     int microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); | 
					
						
							|  |  |  |     PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int hour = PyDateTime_TIME_GET_HOUR(obj); | 
					
						
							|  |  |  |     int minute = PyDateTime_TIME_GET_MINUTE(obj); | 
					
						
							|  |  |  |     int second = PyDateTime_TIME_GET_SECOND(obj); | 
					
						
							|  |  |  |     int microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); | 
					
						
							|  |  |  |     PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int days = PyDateTime_DELTA_GET_DAYS(obj); | 
					
						
							|  |  |  |     int seconds = PyDateTime_DELTA_GET_SECONDS(obj); | 
					
						
							|  |  |  |     int microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Py_BuildValue("(iii)", days, seconds, microseconds); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef test_methods[] = { | 
					
						
							|  |  |  |     {"PyDateTime_DATE_GET",         test_PyDateTime_DATE_GET,       METH_O}, | 
					
						
							|  |  |  |     {"PyDateTime_DELTA_GET",        test_PyDateTime_DELTA_GET,      METH_O}, | 
					
						
							|  |  |  |     {"PyDateTime_GET",              test_PyDateTime_GET,            METH_O}, | 
					
						
							|  |  |  |     {"PyDateTime_TIME_GET",         test_PyDateTime_TIME_GET,       METH_O}, | 
					
						
							|  |  |  |     {"datetime_check_date",         datetime_check_date,            METH_VARARGS}, | 
					
						
							|  |  |  |     {"datetime_check_datetime",     datetime_check_datetime,        METH_VARARGS}, | 
					
						
							|  |  |  |     {"datetime_check_delta",        datetime_check_delta,           METH_VARARGS}, | 
					
						
							|  |  |  |     {"datetime_check_time",         datetime_check_time,            METH_VARARGS}, | 
					
						
							|  |  |  |     {"datetime_check_tzinfo",       datetime_check_tzinfo,          METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_date_fromdate",           get_date_fromdate,              METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_date_fromtimestamp",      get_date_fromtimestamp,         METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_datetime_fromdateandtime", get_datetime_fromdateandtime,  METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_datetime_fromtimestamp",  get_datetime_fromtimestamp,     METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_delta_fromdsu",           get_delta_fromdsu,              METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_time_fromtime",           get_time_fromtime,              METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_time_fromtimeandfold",    get_time_fromtimeandfold,       METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_timezone_utc_capi",       get_timezone_utc_capi,          METH_VARARGS}, | 
					
						
							|  |  |  |     {"get_timezones_offset_zero",   get_timezones_offset_zero,      METH_NOARGS}, | 
					
						
							|  |  |  |     {"make_timezones_capi",         make_timezones_capi,            METH_NOARGS}, | 
					
						
							|  |  |  |     {"test_datetime_capi",          test_datetime_capi,             METH_NOARGS}, | 
					
						
							|  |  |  |     {NULL}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyTestCapi_Init_DateTime(PyObject *mod) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (PyModule_AddFunctions(mod, test_methods) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-06-14 03:05:03 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ---------------------------------------------------------------------------
 | 
					
						
							|  |  |  |  * Test module for subinterpreters. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | _testcapi_datetime_exec(PyObject *mod) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (test_datetime_capi(NULL, NULL) == NULL)  { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyModuleDef_Slot _testcapi_datetime_slots[] = { | 
					
						
							|  |  |  |     {Py_mod_exec, _testcapi_datetime_exec}, | 
					
						
							|  |  |  |     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, | 
					
						
							|  |  |  |     {Py_mod_gil, Py_MOD_GIL_NOT_USED}, | 
					
						
							|  |  |  |     {0, NULL}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyModuleDef _testcapi_datetime_module = { | 
					
						
							|  |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     .m_name = "_testcapi_datetime", | 
					
						
							|  |  |  |     .m_size = 0, | 
					
						
							|  |  |  |     .m_methods = test_methods, | 
					
						
							|  |  |  |     .m_slots = _testcapi_datetime_slots, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMODINIT_FUNC | 
					
						
							|  |  |  | PyInit__testcapi_datetime(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyModuleDef_Init(&_testcapi_datetime_module); | 
					
						
							|  |  |  | } |