LCOV - code coverage report
Current view: | top level - Modules/_testcapi - datetime.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 3 | 168 | 1.8 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 1 | 22 | 4.5 %
|  |  | Branches: | 1 | 86 | 1.2 %

               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", &macro)) {
         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", &macro, &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                 :            :                           &macro,
         177                 :            :                           &year, &month, &day,
         178                 :            :                           &hour, &minute, &second, &microsecond)) {
         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                 :            :                           &macro,
         207                 :            :                           &year, &month, &day,
         208                 :            :                           &hour, &minute, &second, &microsecond,
         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                 :            :                           &macro,
         239                 :            :                           &hour, &minute, &second, &microsecond))
         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                 :            :                           &macro,
         265                 :            :                           &hour, &minute, &second, &microsecond,
         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                 :            :                           &macro,
         292                 :            :                           &days, &seconds, &microseconds)) {
         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, &macro)) {
         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, &macro)) {
         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                 :            : }

Generated by: LCOV version 1.14