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