Branch data Line data Source code
1 : : #include "parts.h"
2 : :
3 : : #include "datetime.h" // PyDateTimeAPI
4 : :
5 : :
6 : : static int test_run_counter = 0;
7 : :
8 : : static PyObject *
9 : 0 : test_datetime_capi(PyObject *self, PyObject *args)
10 : : {
11 [ # # ]: 0 : if (PyDateTimeAPI) {
12 [ # # ]: 0 : if (test_run_counter) {
13 : : /* Probably regrtest.py -R */
14 : 0 : Py_RETURN_NONE;
15 : : }
16 : : else {
17 : 0 : PyErr_SetString(PyExc_AssertionError,
18 : : "PyDateTime_CAPI somehow initialized");
19 : 0 : return NULL;
20 : : }
21 : : }
22 : 0 : test_run_counter++;
23 : 0 : PyDateTime_IMPORT;
24 : :
25 [ # # ]: 0 : if (PyDateTimeAPI) {
26 : 0 : Py_RETURN_NONE;
27 : : }
28 : 0 : return NULL;
29 : : }
30 : :
31 : : /* Functions exposing the C API type checking for testing */
32 : : #define MAKE_DATETIME_CHECK_FUNC(check_method, exact_method) \
33 : : do { \
34 : : PyObject *obj; \
35 : : int exact = 0; \
36 : : if (!PyArg_ParseTuple(args, "O|p", &obj, &exact)) { \
37 : : return NULL; \
38 : : } \
39 : : int rv = exact?exact_method(obj):check_method(obj); \
40 : : if (rv) { \
41 : : Py_RETURN_TRUE; \
42 : : } \
43 : : Py_RETURN_FALSE; \
44 : : } while (0) \
45 : :
46 : : static PyObject *
47 : 0 : datetime_check_date(PyObject *self, PyObject *args)
48 : : {
49 [ # # # # : 0 : MAKE_DATETIME_CHECK_FUNC(PyDate_Check, PyDate_CheckExact);
# # ]
50 : : }
51 : :
52 : : static PyObject *
53 : 0 : datetime_check_time(PyObject *self, PyObject *args)
54 : : {
55 [ # # # # : 0 : MAKE_DATETIME_CHECK_FUNC(PyTime_Check, PyTime_CheckExact);
# # ]
56 : : }
57 : :
58 : : static PyObject *
59 : 0 : datetime_check_datetime(PyObject *self, PyObject *args)
60 : : {
61 [ # # # # : 0 : MAKE_DATETIME_CHECK_FUNC(PyDateTime_Check, PyDateTime_CheckExact);
# # ]
62 : : }
63 : :
64 : : static PyObject *
65 : 0 : datetime_check_delta(PyObject *self, PyObject *args)
66 : : {
67 [ # # # # : 0 : MAKE_DATETIME_CHECK_FUNC(PyDelta_Check, PyDelta_CheckExact);
# # ]
68 : : }
69 : :
70 : : static PyObject *
71 : 0 : datetime_check_tzinfo(PyObject *self, PyObject *args)
72 : : {
73 [ # # # # : 0 : MAKE_DATETIME_CHECK_FUNC(PyTZInfo_Check, PyTZInfo_CheckExact);
# # ]
74 : : }
75 : : #undef MAKE_DATETIME_CHECK_FUNC
76 : :
77 : :
78 : : /* Makes three variations on timezone representing UTC-5:
79 : : 1. timezone with offset and name from PyDateTimeAPI
80 : : 2. timezone with offset and name from PyTimeZone_FromOffsetAndName
81 : : 3. timezone with offset (no name) from PyTimeZone_FromOffset
82 : : */
83 : : static PyObject *
84 : 0 : make_timezones_capi(PyObject *self, PyObject *args)
85 : : {
86 : 0 : PyObject *offset = PyDelta_FromDSU(0, -18000, 0);
87 : 0 : PyObject *name = PyUnicode_FromString("EST");
88 : :
89 : 0 : PyObject *est_zone_capi = PyDateTimeAPI->TimeZone_FromTimeZone(offset, name);
90 : 0 : PyObject *est_zone_macro = PyTimeZone_FromOffsetAndName(offset, name);
91 : 0 : PyObject *est_zone_macro_noname = PyTimeZone_FromOffset(offset);
92 : :
93 : 0 : Py_DecRef(offset);
94 : 0 : Py_DecRef(name);
95 : :
96 : 0 : PyObject *rv = PyTuple_New(3);
97 [ # # ]: 0 : if (rv == NULL) {
98 : 0 : return NULL;
99 : : }
100 : :
101 : 0 : PyTuple_SET_ITEM(rv, 0, est_zone_capi);
102 : 0 : PyTuple_SET_ITEM(rv, 1, est_zone_macro);
103 : 0 : PyTuple_SET_ITEM(rv, 2, est_zone_macro_noname);
104 : :
105 : 0 : return rv;
106 : : }
107 : :
108 : : static PyObject *
109 : 0 : get_timezones_offset_zero(PyObject *self, PyObject *args)
110 : : {
111 : 0 : PyObject *offset = PyDelta_FromDSU(0, 0, 0);
112 : 0 : PyObject *name = PyUnicode_FromString("");
113 : :
114 : : // These two should return the UTC singleton
115 : 0 : PyObject *utc_singleton_0 = PyTimeZone_FromOffset(offset);
116 : 0 : PyObject *utc_singleton_1 = PyTimeZone_FromOffsetAndName(offset, NULL);
117 : :
118 : : // This one will return +00:00 zone, but not the UTC singleton
119 : 0 : PyObject *non_utc_zone = PyTimeZone_FromOffsetAndName(offset, name);
120 : :
121 : 0 : Py_DecRef(offset);
122 : 0 : Py_DecRef(name);
123 : :
124 : 0 : PyObject *rv = PyTuple_New(3);
125 : 0 : PyTuple_SET_ITEM(rv, 0, utc_singleton_0);
126 : 0 : PyTuple_SET_ITEM(rv, 1, utc_singleton_1);
127 : 0 : PyTuple_SET_ITEM(rv, 2, non_utc_zone);
128 : :
129 : 0 : return rv;
130 : : }
131 : :
132 : : static PyObject *
133 : 0 : get_timezone_utc_capi(PyObject *self, PyObject *args)
134 : : {
135 : 0 : int macro = 0;
136 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "|p", ¯o)) {
137 : 0 : return NULL;
138 : : }
139 [ # # ]: 0 : if (macro) {
140 : 0 : return Py_NewRef(PyDateTime_TimeZone_UTC);
141 : : }
142 : 0 : return Py_NewRef(PyDateTimeAPI->TimeZone_UTC);
143 : : }
144 : :
145 : : static PyObject *
146 : 0 : get_date_fromdate(PyObject *self, PyObject *args)
147 : : {
148 : 0 : PyObject *rv = NULL;
149 : : int macro;
150 : : int year, month, day;
151 : :
152 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) {
153 : 0 : return NULL;
154 : : }
155 : :
156 [ # # ]: 0 : if (macro) {
157 : 0 : rv = PyDate_FromDate(year, month, day);
158 : : }
159 : : else {
160 : 0 : rv = PyDateTimeAPI->Date_FromDate(
161 : : year, month, day,
162 : 0 : PyDateTimeAPI->DateType);
163 : : }
164 : 0 : return rv;
165 : : }
166 : :
167 : : static PyObject *
168 : 0 : get_datetime_fromdateandtime(PyObject *self, PyObject *args)
169 : : {
170 : 0 : PyObject *rv = NULL;
171 : : int macro;
172 : : int year, month, day;
173 : : int hour, minute, second, microsecond;
174 : :
175 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "piiiiiii",
176 : : ¯o,
177 : : &year, &month, &day,
178 : : &hour, &minute, &second, µsecond)) {
179 : 0 : return NULL;
180 : : }
181 : :
182 [ # # ]: 0 : if (macro) {
183 : 0 : rv = PyDateTime_FromDateAndTime(
184 : : year, month, day,
185 : : hour, minute, second, microsecond);
186 : : }
187 : : else {
188 : 0 : rv = PyDateTimeAPI->DateTime_FromDateAndTime(
189 : : year, month, day,
190 : : hour, minute, second, microsecond,
191 : : Py_None,
192 : 0 : PyDateTimeAPI->DateTimeType);
193 : : }
194 : 0 : return rv;
195 : : }
196 : :
197 : : static PyObject *
198 : 0 : get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args)
199 : : {
200 : 0 : PyObject *rv = NULL;
201 : : int macro;
202 : : int year, month, day;
203 : : int hour, minute, second, microsecond, fold;
204 : :
205 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "piiiiiiii",
206 : : ¯o,
207 : : &year, &month, &day,
208 : : &hour, &minute, &second, µsecond,
209 : : &fold)) {
210 : 0 : return NULL;
211 : : }
212 : :
213 [ # # ]: 0 : if (macro) {
214 : 0 : rv = PyDateTime_FromDateAndTimeAndFold(
215 : : year, month, day,
216 : : hour, minute, second, microsecond,
217 : : fold);
218 : : }
219 : : else {
220 : 0 : rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(
221 : : year, month, day,
222 : : hour, minute, second, microsecond,
223 : : Py_None,
224 : : fold,
225 : 0 : PyDateTimeAPI->DateTimeType);
226 : : }
227 : 0 : return rv;
228 : : }
229 : :
230 : : static PyObject *
231 : 0 : get_time_fromtime(PyObject *self, PyObject *args)
232 : : {
233 : 0 : PyObject *rv = NULL;
234 : : int macro;
235 : : int hour, minute, second, microsecond;
236 : :
237 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "piiii",
238 : : ¯o,
239 : : &hour, &minute, &second, µsecond))
240 : : {
241 : 0 : return NULL;
242 : : }
243 : :
244 [ # # ]: 0 : if (macro) {
245 : 0 : rv = PyTime_FromTime(hour, minute, second, microsecond);
246 : : }
247 : : else {
248 : 0 : rv = PyDateTimeAPI->Time_FromTime(
249 : : hour, minute, second, microsecond,
250 : : Py_None,
251 : 0 : PyDateTimeAPI->TimeType);
252 : : }
253 : 0 : return rv;
254 : : }
255 : :
256 : : static PyObject *
257 : 0 : get_time_fromtimeandfold(PyObject *self, PyObject *args)
258 : : {
259 : 0 : PyObject *rv = NULL;
260 : : int macro;
261 : : int hour, minute, second, microsecond, fold;
262 : :
263 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "piiiii",
264 : : ¯o,
265 : : &hour, &minute, &second, µsecond,
266 : : &fold)) {
267 : 0 : return NULL;
268 : : }
269 : :
270 [ # # ]: 0 : if (macro) {
271 : 0 : rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold);
272 : : }
273 : : else {
274 : 0 : rv = PyDateTimeAPI->Time_FromTimeAndFold(
275 : : hour, minute, second, microsecond,
276 : : Py_None,
277 : : fold,
278 : 0 : PyDateTimeAPI->TimeType);
279 : : }
280 : 0 : return rv;
281 : : }
282 : :
283 : : static PyObject *
284 : 0 : get_delta_fromdsu(PyObject *self, PyObject *args)
285 : : {
286 : 0 : PyObject *rv = NULL;
287 : : int macro;
288 : : int days, seconds, microseconds;
289 : :
290 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "piii",
291 : : ¯o,
292 : : &days, &seconds, µseconds)) {
293 : 0 : return NULL;
294 : : }
295 : :
296 [ # # ]: 0 : if (macro) {
297 : 0 : rv = PyDelta_FromDSU(days, seconds, microseconds);
298 : : }
299 : : else {
300 : 0 : rv = PyDateTimeAPI->Delta_FromDelta(
301 : : days, seconds, microseconds, 1,
302 : 0 : PyDateTimeAPI->DeltaType);
303 : : }
304 : :
305 : 0 : return rv;
306 : : }
307 : :
308 : : static PyObject *
309 : 0 : get_date_fromtimestamp(PyObject *self, PyObject *args)
310 : : {
311 : 0 : PyObject *tsargs = NULL, *ts = NULL, *rv = NULL;
312 : 0 : int macro = 0;
313 : :
314 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) {
315 : 0 : return NULL;
316 : : }
317 : :
318 : : // Construct the argument tuple
319 [ # # ]: 0 : if ((tsargs = PyTuple_Pack(1, ts)) == NULL) {
320 : 0 : return NULL;
321 : : }
322 : :
323 : : // Pass along to the API function
324 [ # # ]: 0 : if (macro) {
325 : 0 : rv = PyDate_FromTimestamp(tsargs);
326 : : }
327 : : else {
328 : 0 : rv = PyDateTimeAPI->Date_FromTimestamp(
329 : 0 : (PyObject *)PyDateTimeAPI->DateType, tsargs
330 : : );
331 : : }
332 : :
333 : 0 : Py_DECREF(tsargs);
334 : 0 : return rv;
335 : : }
336 : :
337 : : static PyObject *
338 : 0 : get_datetime_fromtimestamp(PyObject *self, PyObject *args)
339 : : {
340 : 0 : int macro = 0;
341 : 0 : int usetz = 0;
342 : 0 : PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL;
343 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) {
344 : 0 : return NULL;
345 : : }
346 : :
347 : : // Construct the argument tuple
348 [ # # ]: 0 : if (usetz) {
349 : 0 : tsargs = PyTuple_Pack(2, ts, tzinfo);
350 : : }
351 : : else {
352 : 0 : tsargs = PyTuple_Pack(1, ts);
353 : : }
354 : :
355 [ # # ]: 0 : if (tsargs == NULL) {
356 : 0 : return NULL;
357 : : }
358 : :
359 : : // Pass along to the API function
360 [ # # ]: 0 : if (macro) {
361 : 0 : rv = PyDateTime_FromTimestamp(tsargs);
362 : : }
363 : : else {
364 : 0 : rv = PyDateTimeAPI->DateTime_FromTimestamp(
365 : 0 : (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL
366 : : );
367 : : }
368 : :
369 : 0 : Py_DECREF(tsargs);
370 : 0 : return rv;
371 : : }
372 : :
373 : : static PyObject *
374 : 0 : test_PyDateTime_GET(PyObject *self, PyObject *obj)
375 : : {
376 : : int year, month, day;
377 : :
378 : 0 : year = PyDateTime_GET_YEAR(obj);
379 : 0 : month = PyDateTime_GET_MONTH(obj);
380 : 0 : day = PyDateTime_GET_DAY(obj);
381 : :
382 : 0 : return Py_BuildValue("(iii)", year, month, day);
383 : : }
384 : :
385 : : static PyObject *
386 : 0 : test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj)
387 : : {
388 : 0 : int hour = PyDateTime_DATE_GET_HOUR(obj);
389 : 0 : int minute = PyDateTime_DATE_GET_MINUTE(obj);
390 : 0 : int second = PyDateTime_DATE_GET_SECOND(obj);
391 : 0 : int microsecond = PyDateTime_DATE_GET_MICROSECOND(obj);
392 [ # # ]: 0 : PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj);
393 : :
394 : 0 : return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo);
395 : : }
396 : :
397 : : static PyObject *
398 : 0 : test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj)
399 : : {
400 : 0 : int hour = PyDateTime_TIME_GET_HOUR(obj);
401 : 0 : int minute = PyDateTime_TIME_GET_MINUTE(obj);
402 : 0 : int second = PyDateTime_TIME_GET_SECOND(obj);
403 : 0 : int microsecond = PyDateTime_TIME_GET_MICROSECOND(obj);
404 [ # # ]: 0 : PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj);
405 : :
406 : 0 : return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo);
407 : : }
408 : :
409 : : static PyObject *
410 : 0 : test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj)
411 : : {
412 : 0 : int days = PyDateTime_DELTA_GET_DAYS(obj);
413 : 0 : int seconds = PyDateTime_DELTA_GET_SECONDS(obj);
414 : 0 : int microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj);
415 : :
416 : 0 : return Py_BuildValue("(iii)", days, seconds, microseconds);
417 : : }
418 : :
419 : : static PyMethodDef test_methods[] = {
420 : : {"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O},
421 : : {"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O},
422 : : {"PyDateTime_GET", test_PyDateTime_GET, METH_O},
423 : : {"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O},
424 : : {"datetime_check_date", datetime_check_date, METH_VARARGS},
425 : : {"datetime_check_datetime", datetime_check_datetime, METH_VARARGS},
426 : : {"datetime_check_delta", datetime_check_delta, METH_VARARGS},
427 : : {"datetime_check_time", datetime_check_time, METH_VARARGS},
428 : : {"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS},
429 : : {"get_date_fromdate", get_date_fromdate, METH_VARARGS},
430 : : {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS},
431 : : {"get_datetime_fromdateandtime", get_datetime_fromdateandtime, METH_VARARGS},
432 : : {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS},
433 : : {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS},
434 : : {"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS},
435 : : {"get_time_fromtime", get_time_fromtime, METH_VARARGS},
436 : : {"get_time_fromtimeandfold", get_time_fromtimeandfold, METH_VARARGS},
437 : : {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS},
438 : : {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS},
439 : : {"make_timezones_capi", make_timezones_capi, METH_NOARGS},
440 : : {"test_datetime_capi", test_datetime_capi, METH_NOARGS},
441 : : {NULL},
442 : : };
443 : :
444 : : int
445 : 2 : _PyTestCapi_Init_DateTime(PyObject *mod)
446 : : {
447 [ - + ]: 2 : if (PyModule_AddFunctions(mod, test_methods) < 0) {
448 : 0 : return -1;
449 : : }
450 : 2 : return 0;
451 : : }
|