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