(root)/
Python-3.11.7/
Modules/
timemodule.c
       1  /* Time module */
       2  
       3  #include "Python.h"
       4  #include "pycore_fileutils.h"     // _Py_BEGIN_SUPPRESS_IPH
       5  #include "pycore_moduleobject.h"  // _PyModule_GetState()
       6  #include "pycore_namespace.h"     // _PyNamespace_New()
       7  #include "pycore_runtime.h"       // _Py_ID()
       8  
       9  #include <ctype.h>
      10  
      11  #ifdef HAVE_SYS_TIMES_H
      12  #  include <sys/times.h>
      13  #endif
      14  #ifdef HAVE_SYS_TYPES_H
      15  #  include <sys/types.h>
      16  #endif
      17  #if defined(HAVE_SYS_RESOURCE_H)
      18  #  include <sys/resource.h>
      19  #endif
      20  #ifdef QUICKWIN
      21  # include <io.h>
      22  #endif
      23  #if defined(HAVE_PTHREAD_H)
      24  #  include <pthread.h>
      25  #endif
      26  #if defined(_AIX)
      27  #   include <sys/thread.h>
      28  #endif
      29  #if defined(__WATCOMC__) && !defined(__QNX__)
      30  #  include <i86.h>
      31  #else
      32  #  ifdef MS_WINDOWS
      33  #    define WIN32_LEAN_AND_MEAN
      34  #    include <windows.h>
      35  #  endif /* MS_WINDOWS */
      36  #endif /* !__WATCOMC__ || __QNX__ */
      37  
      38  #ifdef _Py_MEMORY_SANITIZER
      39  #  include <sanitizer/msan_interface.h>
      40  #endif
      41  
      42  #ifdef _MSC_VER
      43  #  define _Py_timezone _timezone
      44  #  define _Py_daylight _daylight
      45  #  define _Py_tzname _tzname
      46  #else
      47  #  define _Py_timezone timezone
      48  #  define _Py_daylight daylight
      49  #  define _Py_tzname tzname
      50  #endif
      51  
      52  #if defined(__APPLE__ ) && defined(__has_builtin)
      53  #  if __has_builtin(__builtin_available)
      54  #    define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
      55  #  endif
      56  #endif
      57  #ifndef HAVE_CLOCK_GETTIME_RUNTIME
      58  #  define HAVE_CLOCK_GETTIME_RUNTIME 1
      59  #endif
      60  
      61  
      62  #define SEC_TO_NS (1000 * 1000 * 1000)
      63  
      64  
      65  /* Forward declarations */
      66  static int pysleep(_PyTime_t timeout);
      67  
      68  
      69  typedef struct {
      70      PyTypeObject *struct_time_type;
      71  } time_module_state;
      72  
      73  static inline time_module_state*
      74  get_time_state(PyObject *module)
      75  {
      76      void *state = _PyModule_GetState(module);
      77      assert(state != NULL);
      78      return (time_module_state *)state;
      79  }
      80  
      81  
      82  static PyObject*
      83  _PyFloat_FromPyTime(_PyTime_t t)
      84  {
      85      double d = _PyTime_AsSecondsDouble(t);
      86      return PyFloat_FromDouble(d);
      87  }
      88  
      89  
      90  static int
      91  get_system_time(_PyTime_t *t)
      92  {
      93      // Avoid _PyTime_GetSystemClock() which silently ignores errors.
      94      return _PyTime_GetSystemClockWithInfo(t, NULL);
      95  }
      96  
      97  
      98  static PyObject *
      99  time_time(PyObject *self, PyObject *unused)
     100  {
     101      _PyTime_t t;
     102      if (get_system_time(&t) < 0) {
     103          return NULL;
     104      }
     105      return _PyFloat_FromPyTime(t);
     106  }
     107  
     108  
     109  PyDoc_STRVAR(time_doc,
     110  "time() -> floating point number\n\
     111  \n\
     112  Return the current time in seconds since the Epoch.\n\
     113  Fractions of a second may be present if the system clock provides them.");
     114  
     115  static PyObject *
     116  time_time_ns(PyObject *self, PyObject *unused)
     117  {
     118      _PyTime_t t;
     119      if (get_system_time(&t) < 0) {
     120          return NULL;
     121      }
     122      return _PyTime_AsNanosecondsObject(t);
     123  }
     124  
     125  PyDoc_STRVAR(time_ns_doc,
     126  "time_ns() -> int\n\
     127  \n\
     128  Return the current time in nanoseconds since the Epoch.");
     129  
     130  #if defined(HAVE_CLOCK)
     131  
     132  #ifndef CLOCKS_PER_SEC
     133  #  ifdef CLK_TCK
     134  #    define CLOCKS_PER_SEC CLK_TCK
     135  #  else
     136  #    define CLOCKS_PER_SEC 1000000
     137  #  endif
     138  #endif
     139  
     140  static int
     141  _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
     142  {
     143      static int initialized = 0;
     144  
     145      if (!initialized) {
     146          initialized = 1;
     147  
     148          /* Make sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC)
     149             above cannot overflow */
     150          if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) {
     151              PyErr_SetString(PyExc_OverflowError,
     152                              "CLOCKS_PER_SEC is too large");
     153              return -1;
     154          }
     155      }
     156  
     157      if (info) {
     158          info->implementation = "clock()";
     159          info->resolution = 1.0 / (double)CLOCKS_PER_SEC;
     160          info->monotonic = 1;
     161          info->adjustable = 0;
     162      }
     163  
     164      clock_t ticks = clock();
     165      if (ticks == (clock_t)-1) {
     166          PyErr_SetString(PyExc_RuntimeError,
     167                          "the processor time used is not available "
     168                          "or its value cannot be represented");
     169          return -1;
     170      }
     171      _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC);
     172      *tp = _PyTime_FromNanoseconds(ns);
     173      return 0;
     174  }
     175  #endif /* HAVE_CLOCK */
     176  
     177  
     178  #ifdef HAVE_CLOCK_GETTIME
     179  
     180  #ifdef __APPLE__
     181  /*
     182   * The clock_* functions will be removed from the module
     183   * dict entirely when the C API is not available.
     184   */
     185  #pragma clang diagnostic push
     186  #pragma clang diagnostic ignored "-Wunguarded-availability"
     187  #endif
     188  
     189  static PyObject *
     190  time_clock_gettime(PyObject *self, PyObject *args)
     191  {
     192      int ret;
     193      struct timespec tp;
     194  
     195  #if defined(_AIX) && (SIZEOF_LONG == 8)
     196      long clk_id;
     197      if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) {
     198  #else
     199      int clk_id;
     200      if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
     201  #endif
     202          return NULL;
     203      }
     204  
     205      ret = clock_gettime((clockid_t)clk_id, &tp);
     206      if (ret != 0) {
     207          PyErr_SetFromErrno(PyExc_OSError);
     208          return NULL;
     209      }
     210      return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
     211  }
     212  
     213  PyDoc_STRVAR(clock_gettime_doc,
     214  "clock_gettime(clk_id) -> float\n\
     215  \n\
     216  Return the time of the specified clock clk_id.");
     217  
     218  static PyObject *
     219  time_clock_gettime_ns(PyObject *self, PyObject *args)
     220  {
     221      int ret;
     222      int clk_id;
     223      struct timespec ts;
     224      _PyTime_t t;
     225  
     226      if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) {
     227          return NULL;
     228      }
     229  
     230      ret = clock_gettime((clockid_t)clk_id, &ts);
     231      if (ret != 0) {
     232          PyErr_SetFromErrno(PyExc_OSError);
     233          return NULL;
     234      }
     235      if (_PyTime_FromTimespec(&t, &ts) < 0) {
     236          return NULL;
     237      }
     238      return _PyTime_AsNanosecondsObject(t);
     239  }
     240  
     241  PyDoc_STRVAR(clock_gettime_ns_doc,
     242  "clock_gettime_ns(clk_id) -> int\n\
     243  \n\
     244  Return the time of the specified clock clk_id as nanoseconds.");
     245  #endif   /* HAVE_CLOCK_GETTIME */
     246  
     247  #ifdef HAVE_CLOCK_SETTIME
     248  static PyObject *
     249  time_clock_settime(PyObject *self, PyObject *args)
     250  {
     251      int clk_id;
     252      PyObject *obj;
     253      _PyTime_t t;
     254      struct timespec tp;
     255      int ret;
     256  
     257      if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj))
     258          return NULL;
     259  
     260      if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0)
     261          return NULL;
     262  
     263      if (_PyTime_AsTimespec(t, &tp) == -1)
     264          return NULL;
     265  
     266      ret = clock_settime((clockid_t)clk_id, &tp);
     267      if (ret != 0) {
     268          PyErr_SetFromErrno(PyExc_OSError);
     269          return NULL;
     270      }
     271      Py_RETURN_NONE;
     272  }
     273  
     274  PyDoc_STRVAR(clock_settime_doc,
     275  "clock_settime(clk_id, time)\n\
     276  \n\
     277  Set the time of the specified clock clk_id.");
     278  
     279  static PyObject *
     280  time_clock_settime_ns(PyObject *self, PyObject *args)
     281  {
     282      int clk_id;
     283      PyObject *obj;
     284      _PyTime_t t;
     285      struct timespec ts;
     286      int ret;
     287  
     288      if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) {
     289          return NULL;
     290      }
     291  
     292      if (_PyTime_FromNanosecondsObject(&t, obj) < 0) {
     293          return NULL;
     294      }
     295      if (_PyTime_AsTimespec(t, &ts) == -1) {
     296          return NULL;
     297      }
     298  
     299      ret = clock_settime((clockid_t)clk_id, &ts);
     300      if (ret != 0) {
     301          PyErr_SetFromErrno(PyExc_OSError);
     302          return NULL;
     303      }
     304      Py_RETURN_NONE;
     305  }
     306  
     307  PyDoc_STRVAR(clock_settime_ns_doc,
     308  "clock_settime_ns(clk_id, time)\n\
     309  \n\
     310  Set the time of the specified clock clk_id with nanoseconds.");
     311  #endif   /* HAVE_CLOCK_SETTIME */
     312  
     313  #ifdef HAVE_CLOCK_GETRES
     314  static PyObject *
     315  time_clock_getres(PyObject *self, PyObject *args)
     316  {
     317      int ret;
     318      int clk_id;
     319      struct timespec tp;
     320  
     321      if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id))
     322          return NULL;
     323  
     324      ret = clock_getres((clockid_t)clk_id, &tp);
     325      if (ret != 0) {
     326          PyErr_SetFromErrno(PyExc_OSError);
     327          return NULL;
     328      }
     329  
     330      return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
     331  }
     332  
     333  PyDoc_STRVAR(clock_getres_doc,
     334  "clock_getres(clk_id) -> floating point number\n\
     335  \n\
     336  Return the resolution (precision) of the specified clock clk_id.");
     337  
     338  #ifdef __APPLE__
     339  #pragma clang diagnostic pop
     340  #endif
     341  
     342  #endif   /* HAVE_CLOCK_GETRES */
     343  
     344  #ifdef HAVE_PTHREAD_GETCPUCLOCKID
     345  static PyObject *
     346  time_pthread_getcpuclockid(PyObject *self, PyObject *args)
     347  {
     348      unsigned long thread_id;
     349      int err;
     350      clockid_t clk_id;
     351      if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) {
     352          return NULL;
     353      }
     354      err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id);
     355      if (err) {
     356          errno = err;
     357          PyErr_SetFromErrno(PyExc_OSError);
     358          return NULL;
     359      }
     360  #ifdef _Py_MEMORY_SANITIZER
     361      __msan_unpoison(&clk_id, sizeof(clk_id));
     362  #endif
     363      return PyLong_FromLong(clk_id);
     364  }
     365  
     366  PyDoc_STRVAR(pthread_getcpuclockid_doc,
     367  "pthread_getcpuclockid(thread_id) -> int\n\
     368  \n\
     369  Return the clk_id of a thread's CPU time clock.");
     370  #endif /* HAVE_PTHREAD_GETCPUCLOCKID */
     371  
     372  static PyObject *
     373  time_sleep(PyObject *self, PyObject *timeout_obj)
     374  {
     375      _PyTime_t timeout;
     376      if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT))
     377          return NULL;
     378      if (timeout < 0) {
     379          PyErr_SetString(PyExc_ValueError,
     380                          "sleep length must be non-negative");
     381          return NULL;
     382      }
     383      if (pysleep(timeout) != 0) {
     384          return NULL;
     385      }
     386      Py_RETURN_NONE;
     387  }
     388  
     389  PyDoc_STRVAR(sleep_doc,
     390  "sleep(seconds)\n\
     391  \n\
     392  Delay execution for a given number of seconds.  The argument may be\n\
     393  a floating point number for subsecond precision.");
     394  
     395  static PyStructSequence_Field struct_time_type_fields[] = {
     396      {"tm_year", "year, for example, 1993"},
     397      {"tm_mon", "month of year, range [1, 12]"},
     398      {"tm_mday", "day of month, range [1, 31]"},
     399      {"tm_hour", "hours, range [0, 23]"},
     400      {"tm_min", "minutes, range [0, 59]"},
     401      {"tm_sec", "seconds, range [0, 61])"},
     402      {"tm_wday", "day of week, range [0, 6], Monday is 0"},
     403      {"tm_yday", "day of year, range [1, 366]"},
     404      {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"},
     405      {"tm_zone", "abbreviation of timezone name"},
     406      {"tm_gmtoff", "offset from UTC in seconds"},
     407      {0}
     408  };
     409  
     410  static PyStructSequence_Desc struct_time_type_desc = {
     411      "time.struct_time",
     412      "The time value as returned by gmtime(), localtime(), and strptime(), and\n"
     413      " accepted by asctime(), mktime() and strftime().  May be considered as a\n"
     414      " sequence of 9 integers.\n\n"
     415      " Note that several fields' values are not the same as those defined by\n"
     416      " the C language standard for struct tm.  For example, the value of the\n"
     417      " field tm_year is the actual year, not year - 1900.  See individual\n"
     418      " fields' descriptions for details.",
     419      struct_time_type_fields,
     420      9,
     421  };
     422  
     423  #if defined(MS_WINDOWS)
     424  #ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
     425    #define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002
     426  #endif
     427  
     428  static DWORD timer_flags = (DWORD)-1;
     429  #endif
     430  
     431  static PyObject *
     432  tmtotuple(time_module_state *state, struct tm *p
     433  #ifndef HAVE_STRUCT_TM_TM_ZONE
     434          , const char *zone, time_t gmtoff
     435  #endif
     436  )
     437  {
     438      PyObject *v = PyStructSequence_New(state->struct_time_type);
     439      if (v == NULL)
     440          return NULL;
     441  
     442  #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
     443  
     444      SET(0, p->tm_year + 1900);
     445      SET(1, p->tm_mon + 1);         /* Want January == 1 */
     446      SET(2, p->tm_mday);
     447      SET(3, p->tm_hour);
     448      SET(4, p->tm_min);
     449      SET(5, p->tm_sec);
     450      SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
     451      SET(7, p->tm_yday + 1);        /* Want January, 1 == 1 */
     452      SET(8, p->tm_isdst);
     453  #ifdef HAVE_STRUCT_TM_TM_ZONE
     454      PyStructSequence_SET_ITEM(v, 9,
     455          PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape"));
     456      SET(10, p->tm_gmtoff);
     457  #else
     458      PyStructSequence_SET_ITEM(v, 9,
     459          PyUnicode_DecodeLocale(zone, "surrogateescape"));
     460      PyStructSequence_SET_ITEM(v, 10, _PyLong_FromTime_t(gmtoff));
     461  #endif /* HAVE_STRUCT_TM_TM_ZONE */
     462  #undef SET
     463      if (PyErr_Occurred()) {
     464          Py_XDECREF(v);
     465          return NULL;
     466      }
     467  
     468      return v;
     469  }
     470  
     471  /* Parse arg tuple that can contain an optional float-or-None value;
     472     format needs to be "|O:name".
     473     Returns non-zero on success (parallels PyArg_ParseTuple).
     474  */
     475  static int
     476  parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
     477  {
     478      PyObject *ot = NULL;
     479      time_t whent;
     480  
     481      if (!PyArg_ParseTuple(args, format, &ot))
     482          return 0;
     483      if (ot == NULL || ot == Py_None) {
     484          whent = time(NULL);
     485      }
     486      else {
     487          if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1)
     488              return 0;
     489      }
     490      *pwhen = whent;
     491      return 1;
     492  }
     493  
     494  static PyObject *
     495  time_gmtime(PyObject *module, PyObject *args)
     496  {
     497      time_t when;
     498      struct tm buf;
     499  
     500      if (!parse_time_t_args(args, "|O:gmtime", &when))
     501          return NULL;
     502  
     503      errno = 0;
     504      if (_PyTime_gmtime(when, &buf) != 0)
     505          return NULL;
     506  
     507      time_module_state *state = get_time_state(module);
     508  #ifdef HAVE_STRUCT_TM_TM_ZONE
     509      return tmtotuple(state, &buf);
     510  #else
     511      return tmtotuple(state, &buf, "UTC", 0);
     512  #endif
     513  }
     514  
     515  #ifndef HAVE_TIMEGM
     516  static time_t
     517  timegm(struct tm *p)
     518  {
     519      /* XXX: the following implementation will not work for tm_year < 1970.
     520         but it is likely that platforms that don't have timegm do not support
     521         negative timestamps anyways. */
     522      return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 +
     523          (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 -
     524          ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400;
     525  }
     526  #endif
     527  
     528  PyDoc_STRVAR(gmtime_doc,
     529  "gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\
     530                         tm_sec, tm_wday, tm_yday, tm_isdst)\n\
     531  \n\
     532  Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
     533  GMT).  When 'seconds' is not passed in, convert the current time instead.\n\
     534  \n\
     535  If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
     536  attributes only.");
     537  
     538  static PyObject *
     539  time_localtime(PyObject *module, PyObject *args)
     540  {
     541      time_t when;
     542      struct tm buf;
     543  
     544      if (!parse_time_t_args(args, "|O:localtime", &when))
     545          return NULL;
     546      if (_PyTime_localtime(when, &buf) != 0)
     547          return NULL;
     548  
     549      time_module_state *state = get_time_state(module);
     550  #ifdef HAVE_STRUCT_TM_TM_ZONE
     551      return tmtotuple(state, &buf);
     552  #else
     553      {
     554          struct tm local = buf;
     555          char zone[100];
     556          time_t gmtoff;
     557          strftime(zone, sizeof(zone), "%Z", &buf);
     558          gmtoff = timegm(&buf) - when;
     559          return tmtotuple(state, &local, zone, gmtoff);
     560      }
     561  #endif
     562  }
     563  
     564  #if defined(__linux__) && !defined(__GLIBC__)
     565  static const char *utc_string = NULL;
     566  #endif
     567  
     568  PyDoc_STRVAR(localtime_doc,
     569  "localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
     570                            tm_sec,tm_wday,tm_yday,tm_isdst)\n\
     571  \n\
     572  Convert seconds since the Epoch to a time tuple expressing local time.\n\
     573  When 'seconds' is not passed in, convert the current time instead.");
     574  
     575  /* Convert 9-item tuple to tm structure.  Return 1 on success, set
     576   * an exception and return 0 on error.
     577   */
     578  static int
     579  gettmarg(time_module_state *state, PyObject *args,
     580           struct tm *p, const char *format)
     581  {
     582      int y;
     583  
     584      memset((void *) p, '\0', sizeof(struct tm));
     585  
     586      if (!PyTuple_Check(args)) {
     587          PyErr_SetString(PyExc_TypeError,
     588                          "Tuple or struct_time argument required");
     589          return 0;
     590      }
     591  
     592      if (!PyArg_ParseTuple(args, format,
     593                            &y, &p->tm_mon, &p->tm_mday,
     594                            &p->tm_hour, &p->tm_min, &p->tm_sec,
     595                            &p->tm_wday, &p->tm_yday, &p->tm_isdst))
     596          return 0;
     597  
     598      if (y < INT_MIN + 1900) {
     599          PyErr_SetString(PyExc_OverflowError, "year out of range");
     600          return 0;
     601      }
     602  
     603      p->tm_year = y - 1900;
     604      p->tm_mon--;
     605      p->tm_wday = (p->tm_wday + 1) % 7;
     606      p->tm_yday--;
     607  #ifdef HAVE_STRUCT_TM_TM_ZONE
     608      if (Py_IS_TYPE(args, state->struct_time_type)) {
     609          PyObject *item;
     610          item = PyStructSequence_GET_ITEM(args, 9);
     611          if (item != Py_None) {
     612              p->tm_zone = (char *)PyUnicode_AsUTF8(item);
     613              if (p->tm_zone == NULL) {
     614                  return 0;
     615              }
     616  #if defined(__linux__) && !defined(__GLIBC__)
     617              // Make an attempt to return the C library's own timezone strings to
     618              // it. musl refuses to process a tm_zone field unless it produced
     619              // it. See issue #34672.
     620              if (utc_string && strcmp(p->tm_zone, utc_string) == 0) {
     621                  p->tm_zone = utc_string;
     622              }
     623              else if (tzname[0] && strcmp(p->tm_zone, tzname[0]) == 0) {
     624                  p->tm_zone = tzname[0];
     625              }
     626              else if (tzname[1] && strcmp(p->tm_zone, tzname[1]) == 0) {
     627                  p->tm_zone = tzname[1];
     628              }
     629  #endif
     630          }
     631          item = PyStructSequence_GET_ITEM(args, 10);
     632          if (item != Py_None) {
     633              p->tm_gmtoff = PyLong_AsLong(item);
     634              if (PyErr_Occurred())
     635                  return 0;
     636          }
     637      }
     638  #endif /* HAVE_STRUCT_TM_TM_ZONE */
     639      return 1;
     640  }
     641  
     642  /* Check values of the struct tm fields before it is passed to strftime() and
     643   * asctime().  Return 1 if all values are valid, otherwise set an exception
     644   * and returns 0.
     645   */
     646  static int
     647  checktm(struct tm* buf)
     648  {
     649      /* Checks added to make sure strftime() and asctime() does not crash Python by
     650         indexing blindly into some array for a textual representation
     651         by some bad index (fixes bug #897625 and #6608).
     652  
     653         Also support values of zero from Python code for arguments in which
     654         that is out of range by forcing that value to the lowest value that
     655         is valid (fixed bug #1520914).
     656  
     657         Valid ranges based on what is allowed in struct tm:
     658  
     659         - tm_year: [0, max(int)] (1)
     660         - tm_mon: [0, 11] (2)
     661         - tm_mday: [1, 31]
     662         - tm_hour: [0, 23]
     663         - tm_min: [0, 59]
     664         - tm_sec: [0, 60]
     665         - tm_wday: [0, 6] (1)
     666         - tm_yday: [0, 365] (2)
     667         - tm_isdst: [-max(int), max(int)]
     668  
     669         (1) gettmarg() handles bounds-checking.
     670         (2) Python's acceptable range is one greater than the range in C,
     671         thus need to check against automatic decrement by gettmarg().
     672      */
     673      if (buf->tm_mon == -1)
     674          buf->tm_mon = 0;
     675      else if (buf->tm_mon < 0 || buf->tm_mon > 11) {
     676          PyErr_SetString(PyExc_ValueError, "month out of range");
     677          return 0;
     678      }
     679      if (buf->tm_mday == 0)
     680          buf->tm_mday = 1;
     681      else if (buf->tm_mday < 0 || buf->tm_mday > 31) {
     682          PyErr_SetString(PyExc_ValueError, "day of month out of range");
     683          return 0;
     684      }
     685      if (buf->tm_hour < 0 || buf->tm_hour > 23) {
     686          PyErr_SetString(PyExc_ValueError, "hour out of range");
     687          return 0;
     688      }
     689      if (buf->tm_min < 0 || buf->tm_min > 59) {
     690          PyErr_SetString(PyExc_ValueError, "minute out of range");
     691          return 0;
     692      }
     693      if (buf->tm_sec < 0 || buf->tm_sec > 61) {
     694          PyErr_SetString(PyExc_ValueError, "seconds out of range");
     695          return 0;
     696      }
     697      /* tm_wday does not need checking of its upper-bound since taking
     698      ``% 7`` in gettmarg() automatically restricts the range. */
     699      if (buf->tm_wday < 0) {
     700          PyErr_SetString(PyExc_ValueError, "day of week out of range");
     701          return 0;
     702      }
     703      if (buf->tm_yday == -1)
     704          buf->tm_yday = 0;
     705      else if (buf->tm_yday < 0 || buf->tm_yday > 365) {
     706          PyErr_SetString(PyExc_ValueError, "day of year out of range");
     707          return 0;
     708      }
     709      return 1;
     710  }
     711  
     712  #ifdef MS_WINDOWS
     713     /* wcsftime() doesn't format correctly time zones, see issue #10653 */
     714  #  undef HAVE_WCSFTIME
     715  #endif
     716  #define STRFTIME_FORMAT_CODES \
     717  "Commonly used format codes:\n\
     718  \n\
     719  %Y  Year with century as a decimal number.\n\
     720  %m  Month as a decimal number [01,12].\n\
     721  %d  Day of the month as a decimal number [01,31].\n\
     722  %H  Hour (24-hour clock) as a decimal number [00,23].\n\
     723  %M  Minute as a decimal number [00,59].\n\
     724  %S  Second as a decimal number [00,61].\n\
     725  %z  Time zone offset from UTC.\n\
     726  %a  Locale's abbreviated weekday name.\n\
     727  %A  Locale's full weekday name.\n\
     728  %b  Locale's abbreviated month name.\n\
     729  %B  Locale's full month name.\n\
     730  %c  Locale's appropriate date and time representation.\n\
     731  %I  Hour (12-hour clock) as a decimal number [01,12].\n\
     732  %p  Locale's equivalent of either AM or PM.\n\
     733  \n\
     734  Other codes may be available on your platform.  See documentation for\n\
     735  the C library strftime function.\n"
     736  
     737  #ifdef HAVE_STRFTIME
     738  #ifdef HAVE_WCSFTIME
     739  #define time_char wchar_t
     740  #define format_time wcsftime
     741  #define time_strlen wcslen
     742  #else
     743  #define time_char char
     744  #define format_time strftime
     745  #define time_strlen strlen
     746  #endif
     747  
     748  static PyObject *
     749  time_strftime(PyObject *module, PyObject *args)
     750  {
     751      PyObject *tup = NULL;
     752      struct tm buf;
     753      const time_char *fmt;
     754  #ifdef HAVE_WCSFTIME
     755      wchar_t *format;
     756  #else
     757      PyObject *format;
     758  #endif
     759      PyObject *format_arg;
     760      size_t fmtlen, buflen;
     761      time_char *outbuf = NULL;
     762      size_t i;
     763      PyObject *ret = NULL;
     764  
     765      memset((void *) &buf, '\0', sizeof(buf));
     766  
     767      /* Will always expect a unicode string to be passed as format.
     768         Given that there's no str type anymore in py3k this seems safe.
     769      */
     770      if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup))
     771          return NULL;
     772  
     773      time_module_state *state = get_time_state(module);
     774      if (tup == NULL) {
     775          time_t tt = time(NULL);
     776          if (_PyTime_localtime(tt, &buf) != 0)
     777              return NULL;
     778      }
     779      else if (!gettmarg(state, tup, &buf,
     780                         "iiiiiiiii;strftime(): illegal time tuple argument") ||
     781               !checktm(&buf))
     782      {
     783          return NULL;
     784      }
     785  
     786  #if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__)
     787      if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
     788          PyErr_SetString(PyExc_ValueError,
     789                          "strftime() requires year in [1; 9999]");
     790          return NULL;
     791      }
     792  #endif
     793  
     794      /* Normalize tm_isdst just in case someone foolishly implements %Z
     795         based on the assumption that tm_isdst falls within the range of
     796         [-1, 1] */
     797      if (buf.tm_isdst < -1)
     798          buf.tm_isdst = -1;
     799      else if (buf.tm_isdst > 1)
     800          buf.tm_isdst = 1;
     801  
     802  #ifdef HAVE_WCSFTIME
     803      format = PyUnicode_AsWideCharString(format_arg, NULL);
     804      if (format == NULL)
     805          return NULL;
     806      fmt = format;
     807  #else
     808      /* Convert the unicode string to an ascii one */
     809      format = PyUnicode_EncodeLocale(format_arg, "surrogateescape");
     810      if (format == NULL)
     811          return NULL;
     812      fmt = PyBytes_AS_STRING(format);
     813  #endif
     814  
     815  #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME)
     816      /* check that the format string contains only valid directives */
     817      for (outbuf = strchr(fmt, '%');
     818          outbuf != NULL;
     819          outbuf = strchr(outbuf+2, '%'))
     820      {
     821          if (outbuf[1] == '#')
     822              ++outbuf; /* not documented by python, */
     823          if (outbuf[1] == '\0')
     824              break;
     825          if ((outbuf[1] == 'y') && buf.tm_year < 0) {
     826              PyErr_SetString(PyExc_ValueError,
     827                          "format %y requires year >= 1900 on Windows");
     828              Py_DECREF(format);
     829              return NULL;
     830          }
     831      }
     832  #elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME)
     833      for (outbuf = wcschr(fmt, '%');
     834          outbuf != NULL;
     835          outbuf = wcschr(outbuf+2, '%'))
     836      {
     837          if (outbuf[1] == L'\0')
     838              break;
     839          /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0))
     840             returns "0/" instead of "99" */
     841          if (outbuf[1] == L'y' && buf.tm_year < 0) {
     842              PyErr_SetString(PyExc_ValueError,
     843                              "format %y requires year >= 1900 on AIX");
     844              PyMem_Free(format);
     845              return NULL;
     846          }
     847      }
     848  #endif
     849  
     850      fmtlen = time_strlen(fmt);
     851  
     852      /* I hate these functions that presume you know how big the output
     853       * will be ahead of time...
     854       */
     855      for (i = 1024; ; i += i) {
     856          outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
     857          if (outbuf == NULL) {
     858              PyErr_NoMemory();
     859              break;
     860          }
     861  #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
     862          errno = 0;
     863  #endif
     864          _Py_BEGIN_SUPPRESS_IPH
     865          buflen = format_time(outbuf, i, fmt, &buf);
     866          _Py_END_SUPPRESS_IPH
     867  #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
     868          /* VisualStudio .NET 2005 does this properly */
     869          if (buflen == 0 && errno == EINVAL) {
     870              PyErr_SetString(PyExc_ValueError, "Invalid format string");
     871              PyMem_Free(outbuf);
     872              break;
     873          }
     874  #endif
     875          if (buflen > 0 || i >= 256 * fmtlen) {
     876              /* If the buffer is 256 times as long as the format,
     877                 it's probably not failing for lack of room!
     878                 More likely, the format yields an empty result,
     879                 e.g. an empty format, or %Z when the timezone
     880                 is unknown. */
     881  #ifdef HAVE_WCSFTIME
     882              ret = PyUnicode_FromWideChar(outbuf, buflen);
     883  #else
     884              ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape");
     885  #endif
     886              PyMem_Free(outbuf);
     887              break;
     888          }
     889          PyMem_Free(outbuf);
     890      }
     891  #ifdef HAVE_WCSFTIME
     892      PyMem_Free(format);
     893  #else
     894      Py_DECREF(format);
     895  #endif
     896      return ret;
     897  }
     898  
     899  #undef time_char
     900  #undef format_time
     901  PyDoc_STRVAR(strftime_doc,
     902  "strftime(format[, tuple]) -> string\n\
     903  \n\
     904  Convert a time tuple to a string according to a format specification.\n\
     905  See the library reference manual for formatting codes. When the time tuple\n\
     906  is not present, current time as returned by localtime() is used.\n\
     907  \n" STRFTIME_FORMAT_CODES);
     908  #endif /* HAVE_STRFTIME */
     909  
     910  static PyObject *
     911  time_strptime(PyObject *self, PyObject *args)
     912  {
     913      PyObject *module, *func, *result;
     914  
     915      module = PyImport_ImportModule("_strptime");
     916      if (!module)
     917          return NULL;
     918  
     919      func = PyObject_GetAttr(module, &_Py_ID(_strptime_time));
     920      Py_DECREF(module);
     921      if (!func) {
     922          return NULL;
     923      }
     924  
     925      result = PyObject_Call(func, args, NULL);
     926      Py_DECREF(func);
     927      return result;
     928  }
     929  
     930  
     931  PyDoc_STRVAR(strptime_doc,
     932  "strptime(string, format) -> struct_time\n\
     933  \n\
     934  Parse a string to a time tuple according to a format specification.\n\
     935  See the library reference manual for formatting codes (same as\n\
     936  strftime()).\n\
     937  \n" STRFTIME_FORMAT_CODES);
     938  
     939  static PyObject *
     940  _asctime(struct tm *timeptr)
     941  {
     942      /* Inspired by Open Group reference implementation available at
     943       * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */
     944      static const char wday_name[7][4] = {
     945          "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
     946      };
     947      static const char mon_name[12][4] = {
     948          "Jan", "Feb", "Mar", "Apr", "May", "Jun",
     949          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
     950      };
     951      return PyUnicode_FromFormat(
     952          "%s %s%3d %.2d:%.2d:%.2d %d",
     953          wday_name[timeptr->tm_wday],
     954          mon_name[timeptr->tm_mon],
     955          timeptr->tm_mday, timeptr->tm_hour,
     956          timeptr->tm_min, timeptr->tm_sec,
     957          1900 + timeptr->tm_year);
     958  }
     959  
     960  static PyObject *
     961  time_asctime(PyObject *module, PyObject *args)
     962  {
     963      PyObject *tup = NULL;
     964      struct tm buf;
     965  
     966      if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
     967          return NULL;
     968  
     969      time_module_state *state = get_time_state(module);
     970      if (tup == NULL) {
     971          time_t tt = time(NULL);
     972          if (_PyTime_localtime(tt, &buf) != 0)
     973              return NULL;
     974      }
     975      else if (!gettmarg(state, tup, &buf,
     976                         "iiiiiiiii;asctime(): illegal time tuple argument") ||
     977               !checktm(&buf))
     978      {
     979          return NULL;
     980      }
     981      return _asctime(&buf);
     982  }
     983  
     984  PyDoc_STRVAR(asctime_doc,
     985  "asctime([tuple]) -> string\n\
     986  \n\
     987  Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
     988  When the time tuple is not present, current time as returned by localtime()\n\
     989  is used.");
     990  
     991  static PyObject *
     992  time_ctime(PyObject *self, PyObject *args)
     993  {
     994      time_t tt;
     995      struct tm buf;
     996      if (!parse_time_t_args(args, "|O:ctime", &tt))
     997          return NULL;
     998      if (_PyTime_localtime(tt, &buf) != 0)
     999          return NULL;
    1000      return _asctime(&buf);
    1001  }
    1002  
    1003  PyDoc_STRVAR(ctime_doc,
    1004  "ctime(seconds) -> string\n\
    1005  \n\
    1006  Convert a time in seconds since the Epoch to a string in local time.\n\
    1007  This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\
    1008  not present, current time as returned by localtime() is used.");
    1009  
    1010  #ifdef HAVE_MKTIME
    1011  static PyObject *
    1012  time_mktime(PyObject *module, PyObject *tm_tuple)
    1013  {
    1014      struct tm tm;
    1015      time_t tt;
    1016  
    1017      time_module_state *state = get_time_state(module);
    1018      if (!gettmarg(state, tm_tuple, &tm,
    1019                    "iiiiiiiii;mktime(): illegal time tuple argument"))
    1020      {
    1021          return NULL;
    1022      }
    1023  
    1024  #if defined(_AIX) || (defined(__VXWORKS__) && !defined(_WRS_CONFIG_LP64))
    1025      /* bpo-19748: AIX mktime() valid range is 00:00:00 UTC, January 1, 1970
    1026         to 03:14:07 UTC, January 19, 2038. Thanks to the workaround below,
    1027         it is possible to support years in range [1902; 2037] */
    1028      if (tm.tm_year < 2 || tm.tm_year > 137) {
    1029          /* bpo-19748: On AIX, mktime() does not report overflow error
    1030             for timestamp < -2^31 or timestamp > 2**31-1. VxWorks has the
    1031             same issue when working in 32 bit mode. */
    1032          PyErr_SetString(PyExc_OverflowError,
    1033                          "mktime argument out of range");
    1034          return NULL;
    1035      }
    1036  #endif
    1037  
    1038  #ifdef _AIX
    1039      /* bpo-34373: AIX mktime() has an integer overflow for years in range
    1040         [1902; 1969]. Workaround the issue by using a year greater or equal than
    1041         1970 (tm_year >= 70): mktime() behaves correctly in that case
    1042         (ex: properly report errors). tm_year and tm_wday are adjusted after
    1043         mktime() call. */
    1044      int orig_tm_year = tm.tm_year;
    1045      int delta_days = 0;
    1046      while (tm.tm_year < 70) {
    1047          /* Use 4 years to account properly leap years */
    1048          tm.tm_year += 4;
    1049          delta_days -= (366 + (365 * 3));
    1050      }
    1051  #endif
    1052  
    1053      tm.tm_wday = -1;  /* sentinel; original value ignored */
    1054      tt = mktime(&tm);
    1055  
    1056      /* Return value of -1 does not necessarily mean an error, but tm_wday
    1057       * cannot remain set to -1 if mktime succeeded. */
    1058      if (tt == (time_t)(-1)
    1059          /* Return value of -1 does not necessarily mean an error, but
    1060           * tm_wday cannot remain set to -1 if mktime succeeded. */
    1061          && tm.tm_wday == -1)
    1062      {
    1063          PyErr_SetString(PyExc_OverflowError,
    1064                          "mktime argument out of range");
    1065          return NULL;
    1066      }
    1067  
    1068  #ifdef _AIX
    1069      if (delta_days != 0) {
    1070          tm.tm_year = orig_tm_year;
    1071          if (tm.tm_wday != -1) {
    1072              tm.tm_wday = (tm.tm_wday + delta_days) % 7;
    1073          }
    1074          tt += delta_days * (24 * 3600);
    1075      }
    1076  #endif
    1077  
    1078      return PyFloat_FromDouble((double)tt);
    1079  }
    1080  
    1081  PyDoc_STRVAR(mktime_doc,
    1082  "mktime(tuple) -> floating point number\n\
    1083  \n\
    1084  Convert a time tuple in local time to seconds since the Epoch.\n\
    1085  Note that mktime(gmtime(0)) will not generally return zero for most\n\
    1086  time zones; instead the returned value will either be equal to that\n\
    1087  of the timezone or altzone attributes on the time module.");
    1088  #endif /* HAVE_MKTIME */
    1089  
    1090  #ifdef HAVE_WORKING_TZSET
    1091  static int init_timezone(PyObject *module);
    1092  
    1093  static PyObject *
    1094  time_tzset(PyObject *self, PyObject *unused)
    1095  {
    1096      PyObject* m;
    1097  
    1098      m = PyImport_ImportModule("time");
    1099      if (m == NULL) {
    1100          return NULL;
    1101      }
    1102  
    1103      tzset();
    1104  
    1105      /* Reset timezone, altzone, daylight and tzname */
    1106      if (init_timezone(m) < 0) {
    1107           return NULL;
    1108      }
    1109      Py_DECREF(m);
    1110      if (PyErr_Occurred())
    1111          return NULL;
    1112  
    1113      Py_RETURN_NONE;
    1114  }
    1115  
    1116  PyDoc_STRVAR(tzset_doc,
    1117  "tzset()\n\
    1118  \n\
    1119  Initialize, or reinitialize, the local timezone to the value stored in\n\
    1120  os.environ['TZ']. The TZ environment variable should be specified in\n\
    1121  standard Unix timezone format as documented in the tzset man page\n\
    1122  (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
    1123  fall back to UTC. If the TZ environment variable is not set, the local\n\
    1124  timezone is set to the systems best guess of wallclock time.\n\
    1125  Changing the TZ environment variable without calling tzset *may* change\n\
    1126  the local timezone used by methods such as localtime, but this behaviour\n\
    1127  should not be relied on.");
    1128  #endif /* HAVE_WORKING_TZSET */
    1129  
    1130  
    1131  static int
    1132  get_monotonic(_PyTime_t *t)
    1133  {
    1134      // Avoid _PyTime_GetMonotonicClock() which silently ignores errors.
    1135      return _PyTime_GetMonotonicClockWithInfo(t, NULL);
    1136  }
    1137  
    1138  
    1139  static PyObject *
    1140  time_monotonic(PyObject *self, PyObject *unused)
    1141  {
    1142      _PyTime_t t;
    1143      if (get_monotonic(&t) < 0) {
    1144          return NULL;
    1145      }
    1146      return _PyFloat_FromPyTime(t);
    1147  }
    1148  
    1149  PyDoc_STRVAR(monotonic_doc,
    1150  "monotonic() -> float\n\
    1151  \n\
    1152  Monotonic clock, cannot go backward.");
    1153  
    1154  static PyObject *
    1155  time_monotonic_ns(PyObject *self, PyObject *unused)
    1156  {
    1157      _PyTime_t t;
    1158      if (get_monotonic(&t) < 0) {
    1159          return NULL;
    1160      }
    1161      return _PyTime_AsNanosecondsObject(t);
    1162  }
    1163  
    1164  PyDoc_STRVAR(monotonic_ns_doc,
    1165  "monotonic_ns() -> int\n\
    1166  \n\
    1167  Monotonic clock, cannot go backward, as nanoseconds.");
    1168  
    1169  
    1170  static int
    1171  get_perf_counter(_PyTime_t *t)
    1172  {
    1173      // Avoid _PyTime_GetPerfCounter() which silently ignores errors.
    1174      return _PyTime_GetPerfCounterWithInfo(t, NULL);
    1175  }
    1176  
    1177  
    1178  static PyObject *
    1179  time_perf_counter(PyObject *self, PyObject *unused)
    1180  {
    1181      _PyTime_t t;
    1182      if (get_perf_counter(&t) < 0) {
    1183          return NULL;
    1184      }
    1185      return _PyFloat_FromPyTime(t);
    1186  }
    1187  
    1188  PyDoc_STRVAR(perf_counter_doc,
    1189  "perf_counter() -> float\n\
    1190  \n\
    1191  Performance counter for benchmarking.");
    1192  
    1193  
    1194  static PyObject *
    1195  time_perf_counter_ns(PyObject *self, PyObject *unused)
    1196  {
    1197      _PyTime_t t;
    1198      if (get_perf_counter(&t) < 0) {
    1199          return NULL;
    1200      }
    1201      return _PyTime_AsNanosecondsObject(t);
    1202  }
    1203  
    1204  PyDoc_STRVAR(perf_counter_ns_doc,
    1205  "perf_counter_ns() -> int\n\
    1206  \n\
    1207  Performance counter for benchmarking as nanoseconds.");
    1208  
    1209  static int
    1210  _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
    1211  {
    1212  #if defined(MS_WINDOWS)
    1213      HANDLE process;
    1214      FILETIME creation_time, exit_time, kernel_time, user_time;
    1215      ULARGE_INTEGER large;
    1216      _PyTime_t ktime, utime, t;
    1217      BOOL ok;
    1218  
    1219      process = GetCurrentProcess();
    1220      ok = GetProcessTimes(process, &creation_time, &exit_time,
    1221                           &kernel_time, &user_time);
    1222      if (!ok) {
    1223          PyErr_SetFromWindowsErr(0);
    1224          return -1;
    1225      }
    1226  
    1227      if (info) {
    1228          info->implementation = "GetProcessTimes()";
    1229          info->resolution = 1e-7;
    1230          info->monotonic = 1;
    1231          info->adjustable = 0;
    1232      }
    1233  
    1234      large.u.LowPart = kernel_time.dwLowDateTime;
    1235      large.u.HighPart = kernel_time.dwHighDateTime;
    1236      ktime = large.QuadPart;
    1237  
    1238      large.u.LowPart = user_time.dwLowDateTime;
    1239      large.u.HighPart = user_time.dwHighDateTime;
    1240      utime = large.QuadPart;
    1241  
    1242      /* ktime and utime have a resolution of 100 nanoseconds */
    1243      t = _PyTime_FromNanoseconds((ktime + utime) * 100);
    1244      *tp = t;
    1245      return 0;
    1246  #else
    1247  
    1248      /* clock_gettime */
    1249  #if defined(HAVE_CLOCK_GETTIME) \
    1250      && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF))
    1251      struct timespec ts;
    1252  
    1253      if (HAVE_CLOCK_GETTIME_RUNTIME) {
    1254  
    1255  #ifdef CLOCK_PROF
    1256          const clockid_t clk_id = CLOCK_PROF;
    1257          const char *function = "clock_gettime(CLOCK_PROF)";
    1258  #else
    1259          const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
    1260          const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
    1261  #endif
    1262  
    1263          if (clock_gettime(clk_id, &ts) == 0) {
    1264              if (info) {
    1265                  struct timespec res;
    1266                  info->implementation = function;
    1267                  info->monotonic = 1;
    1268                  info->adjustable = 0;
    1269                  if (clock_getres(clk_id, &res)) {
    1270                      PyErr_SetFromErrno(PyExc_OSError);
    1271                      return -1;
    1272                  }
    1273                  info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
    1274              }
    1275  
    1276              if (_PyTime_FromTimespec(tp, &ts) < 0) {
    1277                  return -1;
    1278              }
    1279              return 0;
    1280          }
    1281      }
    1282  #endif
    1283  
    1284      /* getrusage(RUSAGE_SELF) */
    1285  #if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRUSAGE)
    1286      struct rusage ru;
    1287  
    1288      if (getrusage(RUSAGE_SELF, &ru) == 0) {
    1289          _PyTime_t utime, stime;
    1290  
    1291          if (info) {
    1292              info->implementation = "getrusage(RUSAGE_SELF)";
    1293              info->monotonic = 1;
    1294              info->adjustable = 0;
    1295              info->resolution = 1e-6;
    1296          }
    1297  
    1298          if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) {
    1299              return -1;
    1300          }
    1301          if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) {
    1302              return -1;
    1303          }
    1304  
    1305          _PyTime_t total = utime + stime;
    1306          *tp = total;
    1307          return 0;
    1308      }
    1309  #endif
    1310  
    1311      /* times() */
    1312  #ifdef HAVE_TIMES
    1313      struct tms t;
    1314  
    1315      if (times(&t) != (clock_t)-1) {
    1316          static long ticks_per_second = -1;
    1317  
    1318          if (ticks_per_second == -1) {
    1319              long freq;
    1320  #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
    1321              freq = sysconf(_SC_CLK_TCK);
    1322              if (freq < 1) {
    1323                  freq = -1;
    1324              }
    1325  #elif defined(HZ)
    1326              freq = HZ;
    1327  #else
    1328              freq = 60; /* magic fallback value; may be bogus */
    1329  #endif
    1330  
    1331              if (freq != -1) {
    1332                  /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second)
    1333                     cannot overflow below */
    1334  #if LONG_MAX > _PyTime_MAX / SEC_TO_NS
    1335                  if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) {
    1336                      PyErr_SetString(PyExc_OverflowError,
    1337                                      "_SC_CLK_TCK is too large");
    1338                      return -1;
    1339                  }
    1340  #endif
    1341  
    1342                  ticks_per_second = freq;
    1343              }
    1344          }
    1345  
    1346          if (ticks_per_second != -1) {
    1347              if (info) {
    1348                  info->implementation = "times()";
    1349                  info->monotonic = 1;
    1350                  info->adjustable = 0;
    1351                  info->resolution = 1.0 / (double)ticks_per_second;
    1352              }
    1353  
    1354              _PyTime_t ns;
    1355              ns = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second);
    1356              ns += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second);
    1357              *tp = _PyTime_FromNanoseconds(ns);
    1358              return 0;
    1359          }
    1360      }
    1361  #endif
    1362  
    1363      /* clock */
    1364      /* Currently, Python 3 requires clock() to build: see issue #22624 */
    1365      return _PyTime_GetClockWithInfo(tp, info);
    1366  #endif
    1367  }
    1368  
    1369  static PyObject *
    1370  time_process_time(PyObject *self, PyObject *unused)
    1371  {
    1372      _PyTime_t t;
    1373      if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
    1374          return NULL;
    1375      }
    1376      return _PyFloat_FromPyTime(t);
    1377  }
    1378  
    1379  PyDoc_STRVAR(process_time_doc,
    1380  "process_time() -> float\n\
    1381  \n\
    1382  Process time for profiling: sum of the kernel and user-space CPU time.");
    1383  
    1384  static PyObject *
    1385  time_process_time_ns(PyObject *self, PyObject *unused)
    1386  {
    1387      _PyTime_t t;
    1388      if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) {
    1389          return NULL;
    1390      }
    1391      return _PyTime_AsNanosecondsObject(t);
    1392  }
    1393  
    1394  PyDoc_STRVAR(process_time_ns_doc,
    1395  "process_time() -> int\n\
    1396  \n\
    1397  Process time for profiling as nanoseconds:\n\
    1398  sum of the kernel and user-space CPU time.");
    1399  
    1400  
    1401  #if defined(MS_WINDOWS)
    1402  #define HAVE_THREAD_TIME
    1403  static int
    1404  _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
    1405  {
    1406      HANDLE thread;
    1407      FILETIME creation_time, exit_time, kernel_time, user_time;
    1408      ULARGE_INTEGER large;
    1409      _PyTime_t ktime, utime, t;
    1410      BOOL ok;
    1411  
    1412      thread =  GetCurrentThread();
    1413      ok = GetThreadTimes(thread, &creation_time, &exit_time,
    1414                          &kernel_time, &user_time);
    1415      if (!ok) {
    1416          PyErr_SetFromWindowsErr(0);
    1417          return -1;
    1418      }
    1419  
    1420      if (info) {
    1421          info->implementation = "GetThreadTimes()";
    1422          info->resolution = 1e-7;
    1423          info->monotonic = 1;
    1424          info->adjustable = 0;
    1425      }
    1426  
    1427      large.u.LowPart = kernel_time.dwLowDateTime;
    1428      large.u.HighPart = kernel_time.dwHighDateTime;
    1429      ktime = large.QuadPart;
    1430  
    1431      large.u.LowPart = user_time.dwLowDateTime;
    1432      large.u.HighPart = user_time.dwHighDateTime;
    1433      utime = large.QuadPart;
    1434  
    1435      /* ktime and utime have a resolution of 100 nanoseconds */
    1436      t = _PyTime_FromNanoseconds((ktime + utime) * 100);
    1437      *tp = t;
    1438      return 0;
    1439  }
    1440  
    1441  #elif defined(_AIX)
    1442  #define HAVE_THREAD_TIME
    1443  static int
    1444  _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
    1445  {
    1446      /* bpo-40192: On AIX, thread_cputime() is preferred: it has nanosecond
    1447         resolution, whereas clock_gettime(CLOCK_THREAD_CPUTIME_ID)
    1448         has a resolution of 10 ms. */
    1449      thread_cputime_t tc;
    1450      if (thread_cputime(-1, &tc) != 0) {
    1451          PyErr_SetFromErrno(PyExc_OSError);
    1452          return -1;
    1453      }
    1454  
    1455      if (info) {
    1456          info->implementation = "thread_cputime()";
    1457          info->monotonic = 1;
    1458          info->adjustable = 0;
    1459          info->resolution = 1e-9;
    1460      }
    1461      *tp = _PyTime_FromNanoseconds(tc.stime + tc.utime);
    1462      return 0;
    1463  }
    1464  
    1465  #elif defined(__sun) && defined(__SVR4)
    1466  #define HAVE_THREAD_TIME
    1467  static int
    1468  _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
    1469  {
    1470      /* bpo-35455: On Solaris, CLOCK_THREAD_CPUTIME_ID clock is not always
    1471         available; use gethrvtime() to substitute this functionality. */
    1472      if (info) {
    1473          info->implementation = "gethrvtime()";
    1474          info->resolution = 1e-9;
    1475          info->monotonic = 1;
    1476          info->adjustable = 0;
    1477      }
    1478      *tp = _PyTime_FromNanoseconds(gethrvtime());
    1479      return 0;
    1480  }
    1481  
    1482  #elif defined(HAVE_CLOCK_GETTIME) && \
    1483        defined(CLOCK_PROCESS_CPUTIME_ID) && \
    1484        !defined(__EMSCRIPTEN__) && !defined(__wasi__)
    1485  #define HAVE_THREAD_TIME
    1486  
    1487  #if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability)
    1488  static int
    1489  _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
    1490       __attribute__((availability(macos, introduced=10.12)))
    1491       __attribute__((availability(ios, introduced=10.0)))
    1492       __attribute__((availability(tvos, introduced=10.0)))
    1493       __attribute__((availability(watchos, introduced=3.0)));
    1494  #endif
    1495  
    1496  static int
    1497  _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
    1498  {
    1499      struct timespec ts;
    1500      const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID;
    1501      const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)";
    1502  
    1503      if (clock_gettime(clk_id, &ts)) {
    1504          PyErr_SetFromErrno(PyExc_OSError);
    1505          return -1;
    1506      }
    1507      if (info) {
    1508          struct timespec res;
    1509          info->implementation = function;
    1510          info->monotonic = 1;
    1511          info->adjustable = 0;
    1512          if (clock_getres(clk_id, &res)) {
    1513              PyErr_SetFromErrno(PyExc_OSError);
    1514              return -1;
    1515          }
    1516          info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
    1517      }
    1518  
    1519      if (_PyTime_FromTimespec(tp, &ts) < 0) {
    1520          return -1;
    1521      }
    1522      return 0;
    1523  }
    1524  #endif
    1525  
    1526  #ifdef HAVE_THREAD_TIME
    1527  #ifdef __APPLE__
    1528  /*
    1529   * The clock_* functions will be removed from the module
    1530   * dict entirely when the C API is not available.
    1531   */
    1532  #pragma clang diagnostic push
    1533  #pragma clang diagnostic ignored "-Wunguarded-availability"
    1534  #endif
    1535  
    1536  static PyObject *
    1537  time_thread_time(PyObject *self, PyObject *unused)
    1538  {
    1539      _PyTime_t t;
    1540      if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
    1541          return NULL;
    1542      }
    1543      return _PyFloat_FromPyTime(t);
    1544  }
    1545  
    1546  PyDoc_STRVAR(thread_time_doc,
    1547  "thread_time() -> float\n\
    1548  \n\
    1549  Thread time for profiling: sum of the kernel and user-space CPU time.");
    1550  
    1551  static PyObject *
    1552  time_thread_time_ns(PyObject *self, PyObject *unused)
    1553  {
    1554      _PyTime_t t;
    1555      if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
    1556          return NULL;
    1557      }
    1558      return _PyTime_AsNanosecondsObject(t);
    1559  }
    1560  
    1561  PyDoc_STRVAR(thread_time_ns_doc,
    1562  "thread_time() -> int\n\
    1563  \n\
    1564  Thread time for profiling as nanoseconds:\n\
    1565  sum of the kernel and user-space CPU time.");
    1566  
    1567  #ifdef __APPLE__
    1568  #pragma clang diagnostic pop
    1569  #endif
    1570  
    1571  #endif
    1572  
    1573  
    1574  static PyObject *
    1575  time_get_clock_info(PyObject *self, PyObject *args)
    1576  {
    1577      char *name;
    1578      _Py_clock_info_t info;
    1579      PyObject *obj = NULL, *dict, *ns;
    1580      _PyTime_t t;
    1581  
    1582      if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) {
    1583          return NULL;
    1584      }
    1585  
    1586  #ifdef Py_DEBUG
    1587      info.implementation = NULL;
    1588      info.monotonic = -1;
    1589      info.adjustable = -1;
    1590      info.resolution = -1.0;
    1591  #else
    1592      info.implementation = "";
    1593      info.monotonic = 0;
    1594      info.adjustable = 0;
    1595      info.resolution = 1.0;
    1596  #endif
    1597  
    1598      if (strcmp(name, "time") == 0) {
    1599          if (_PyTime_GetSystemClockWithInfo(&t, &info) < 0) {
    1600              return NULL;
    1601          }
    1602      }
    1603      else if (strcmp(name, "monotonic") == 0) {
    1604          if (_PyTime_GetMonotonicClockWithInfo(&t, &info) < 0) {
    1605              return NULL;
    1606          }
    1607      }
    1608      else if (strcmp(name, "perf_counter") == 0) {
    1609          if (_PyTime_GetPerfCounterWithInfo(&t, &info) < 0) {
    1610              return NULL;
    1611          }
    1612      }
    1613      else if (strcmp(name, "process_time") == 0) {
    1614          if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) {
    1615              return NULL;
    1616          }
    1617      }
    1618  #ifdef HAVE_THREAD_TIME
    1619      else if (strcmp(name, "thread_time") == 0) {
    1620  
    1621  #ifdef __APPLE__
    1622          if (HAVE_CLOCK_GETTIME_RUNTIME) {
    1623  #endif
    1624              if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) {
    1625                  return NULL;
    1626              }
    1627  #ifdef __APPLE__
    1628          } else {
    1629              PyErr_SetString(PyExc_ValueError, "unknown clock");
    1630              return NULL;
    1631          }
    1632  #endif
    1633      }
    1634  #endif
    1635      else {
    1636          PyErr_SetString(PyExc_ValueError, "unknown clock");
    1637          return NULL;
    1638      }
    1639  
    1640      dict = PyDict_New();
    1641      if (dict == NULL) {
    1642          return NULL;
    1643      }
    1644  
    1645      assert(info.implementation != NULL);
    1646      obj = PyUnicode_FromString(info.implementation);
    1647      if (obj == NULL) {
    1648          goto error;
    1649      }
    1650      if (PyDict_SetItemString(dict, "implementation", obj) == -1) {
    1651          goto error;
    1652      }
    1653      Py_CLEAR(obj);
    1654  
    1655      assert(info.monotonic != -1);
    1656      obj = PyBool_FromLong(info.monotonic);
    1657      if (obj == NULL) {
    1658          goto error;
    1659      }
    1660      if (PyDict_SetItemString(dict, "monotonic", obj) == -1) {
    1661          goto error;
    1662      }
    1663      Py_CLEAR(obj);
    1664  
    1665      assert(info.adjustable != -1);
    1666      obj = PyBool_FromLong(info.adjustable);
    1667      if (obj == NULL) {
    1668          goto error;
    1669      }
    1670      if (PyDict_SetItemString(dict, "adjustable", obj) == -1) {
    1671          goto error;
    1672      }
    1673      Py_CLEAR(obj);
    1674  
    1675      assert(info.resolution > 0.0);
    1676      assert(info.resolution <= 1.0);
    1677      obj = PyFloat_FromDouble(info.resolution);
    1678      if (obj == NULL) {
    1679          goto error;
    1680      }
    1681      if (PyDict_SetItemString(dict, "resolution", obj) == -1) {
    1682          goto error;
    1683      }
    1684      Py_CLEAR(obj);
    1685  
    1686      ns = _PyNamespace_New(dict);
    1687      Py_DECREF(dict);
    1688      return ns;
    1689  
    1690  error:
    1691      Py_DECREF(dict);
    1692      Py_XDECREF(obj);
    1693      return NULL;
    1694  }
    1695  
    1696  PyDoc_STRVAR(get_clock_info_doc,
    1697  "get_clock_info(name: str) -> dict\n\
    1698  \n\
    1699  Get information of the specified clock.");
    1700  
    1701  #ifndef HAVE_DECL_TZNAME
    1702  static void
    1703  get_zone(char *zone, int n, struct tm *p)
    1704  {
    1705  #ifdef HAVE_STRUCT_TM_TM_ZONE
    1706      strncpy(zone, p->tm_zone ? p->tm_zone : "   ", n);
    1707  #else
    1708      tzset();
    1709      strftime(zone, n, "%Z", p);
    1710  #endif
    1711  }
    1712  
    1713  static time_t
    1714  get_gmtoff(time_t t, struct tm *p)
    1715  {
    1716  #ifdef HAVE_STRUCT_TM_TM_ZONE
    1717      return p->tm_gmtoff;
    1718  #else
    1719      return timegm(p) - t;
    1720  #endif
    1721  }
    1722  #endif // !HAVE_DECL_TZNAME
    1723  
    1724  static int
    1725  init_timezone(PyObject *m)
    1726  {
    1727      assert(!PyErr_Occurred());
    1728  
    1729      /* This code moved from PyInit_time wholesale to allow calling it from
    1730      time_tzset. In the future, some parts of it can be moved back
    1731      (for platforms that don't HAVE_WORKING_TZSET, when we know what they
    1732      are), and the extraneous calls to tzset(3) should be removed.
    1733      I haven't done this yet, as I don't want to change this code as
    1734      little as possible when introducing the time.tzset and time.tzsetwall
    1735      methods. This should simply be a method of doing the following once,
    1736      at the top of this function and removing the call to tzset() from
    1737      time_tzset():
    1738  
    1739          #ifdef HAVE_TZSET
    1740          tzset()
    1741          #endif
    1742  
    1743      And I'm lazy and hate C so nyer.
    1744       */
    1745  #ifdef HAVE_DECL_TZNAME
    1746      PyObject *otz0, *otz1;
    1747      tzset();
    1748      PyModule_AddIntConstant(m, "timezone", _Py_timezone);
    1749  #ifdef HAVE_ALTZONE
    1750      PyModule_AddIntConstant(m, "altzone", altzone);
    1751  #else
    1752      PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600);
    1753  #endif
    1754      PyModule_AddIntConstant(m, "daylight", _Py_daylight);
    1755  #ifdef MS_WINDOWS
    1756      TIME_ZONE_INFORMATION tzinfo = {0};
    1757      GetTimeZoneInformation(&tzinfo);
    1758      otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1);
    1759      if (otz0 == NULL) {
    1760          return -1;
    1761      }
    1762      otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1);
    1763      if (otz1 == NULL) {
    1764          Py_DECREF(otz0);
    1765          return -1;
    1766      }
    1767  #else
    1768      otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape");
    1769      if (otz0 == NULL) {
    1770          return -1;
    1771      }
    1772      otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape");
    1773      if (otz1 == NULL) {
    1774          Py_DECREF(otz0);
    1775          return -1;
    1776      }
    1777  #endif // MS_WINDOWS
    1778      if (_PyModule_Add(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)) < 0) {
    1779          return -1;
    1780      }
    1781  #else // !HAVE_DECL_TZNAME
    1782      static const time_t YEAR = (365 * 24 + 6) * 3600;
    1783      time_t t;
    1784      struct tm p;
    1785      time_t janzone_t, julyzone_t;
    1786      char janname[10], julyname[10];
    1787      t = (time((time_t *)0) / YEAR) * YEAR;
    1788      _PyTime_localtime(t, &p);
    1789      get_zone(janname, 9, &p);
    1790      janzone_t = -get_gmtoff(t, &p);
    1791      janname[9] = '\0';
    1792      t += YEAR/2;
    1793      _PyTime_localtime(t, &p);
    1794      get_zone(julyname, 9, &p);
    1795      julyzone_t = -get_gmtoff(t, &p);
    1796      julyname[9] = '\0';
    1797  
    1798      /* Sanity check, don't check for the validity of timezones.
    1799         In practice, it should be more in range -12 hours .. +14 hours. */
    1800  #define MAX_TIMEZONE (48 * 3600)
    1801      if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE
    1802          || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE)
    1803      {
    1804          PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset");
    1805          return -1;
    1806      }
    1807      int janzone = (int)janzone_t;
    1808      int julyzone = (int)julyzone_t;
    1809  
    1810      PyObject *tzname_obj;
    1811      if (janzone < julyzone) {
    1812          /* DST is reversed in the southern hemisphere */
    1813          PyModule_AddIntConstant(m, "timezone", julyzone);
    1814          PyModule_AddIntConstant(m, "altzone", janzone);
    1815          PyModule_AddIntConstant(m, "daylight", janzone != julyzone);
    1816          tzname_obj = Py_BuildValue("(zz)", julyname, janname);
    1817      } else {
    1818          PyModule_AddIntConstant(m, "timezone", janzone);
    1819          PyModule_AddIntConstant(m, "altzone", julyzone);
    1820          PyModule_AddIntConstant(m, "daylight", janzone != julyzone);
    1821          tzname_obj = Py_BuildValue("(zz)", janname, julyname);
    1822      }
    1823      if (_PyModule_Add(m, "tzname", tzname_obj) < 0) {
    1824          return -1;
    1825      }
    1826  #endif // !HAVE_DECL_TZNAME
    1827  
    1828      if (PyErr_Occurred()) {
    1829          return -1;
    1830      }
    1831      return 0;
    1832  }
    1833  
    1834  
    1835  static PyMethodDef time_methods[] = {
    1836      {"time",            time_time, METH_NOARGS, time_doc},
    1837      {"time_ns",         time_time_ns, METH_NOARGS, time_ns_doc},
    1838  #ifdef HAVE_CLOCK_GETTIME
    1839      {"clock_gettime",   time_clock_gettime, METH_VARARGS, clock_gettime_doc},
    1840      {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc},
    1841  #endif
    1842  #ifdef HAVE_CLOCK_SETTIME
    1843      {"clock_settime",   time_clock_settime, METH_VARARGS, clock_settime_doc},
    1844      {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc},
    1845  #endif
    1846  #ifdef HAVE_CLOCK_GETRES
    1847      {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
    1848  #endif
    1849  #ifdef HAVE_PTHREAD_GETCPUCLOCKID
    1850      {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc},
    1851  #endif
    1852      {"sleep",           time_sleep, METH_O, sleep_doc},
    1853      {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
    1854      {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
    1855      {"asctime",         time_asctime, METH_VARARGS, asctime_doc},
    1856      {"ctime",           time_ctime, METH_VARARGS, ctime_doc},
    1857  #ifdef HAVE_MKTIME
    1858      {"mktime",          time_mktime, METH_O, mktime_doc},
    1859  #endif
    1860  #ifdef HAVE_STRFTIME
    1861      {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
    1862  #endif
    1863      {"strptime",        time_strptime, METH_VARARGS, strptime_doc},
    1864  #ifdef HAVE_WORKING_TZSET
    1865      {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
    1866  #endif
    1867      {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
    1868      {"monotonic_ns",    time_monotonic_ns, METH_NOARGS, monotonic_ns_doc},
    1869      {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
    1870      {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc},
    1871  #ifdef HAVE_THREAD_TIME
    1872      {"thread_time",     time_thread_time, METH_NOARGS, thread_time_doc},
    1873      {"thread_time_ns",  time_thread_time_ns, METH_NOARGS, thread_time_ns_doc},
    1874  #endif
    1875      {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
    1876      {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc},
    1877      {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},
    1878      {NULL,              NULL}           /* sentinel */
    1879  };
    1880  
    1881  
    1882  PyDoc_STRVAR(module_doc,
    1883  "This module provides various functions to manipulate time values.\n\
    1884  \n\
    1885  There are two standard representations of time.  One is the number\n\
    1886  of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\n\
    1887  or a floating point number (to represent fractions of seconds).\n\
    1888  The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
    1889  The actual value can be retrieved by calling gmtime(0).\n\
    1890  \n\
    1891  The other representation is a tuple of 9 integers giving local time.\n\
    1892  The tuple items are:\n\
    1893    year (including century, e.g. 1998)\n\
    1894    month (1-12)\n\
    1895    day (1-31)\n\
    1896    hours (0-23)\n\
    1897    minutes (0-59)\n\
    1898    seconds (0-59)\n\
    1899    weekday (0-6, Monday is 0)\n\
    1900    Julian day (day in the year, 1-366)\n\
    1901    DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
    1902  If the DST flag is 0, the time is given in the regular time zone;\n\
    1903  if it is 1, the time is given in the DST time zone;\n\
    1904  if it is -1, mktime() should guess based on the date and time.\n");
    1905  
    1906  
    1907  static int
    1908  time_exec(PyObject *module)
    1909  {
    1910      time_module_state *state = get_time_state(module);
    1911  #if defined(__APPLE__) && defined(HAVE_CLOCK_GETTIME)
    1912      if (HAVE_CLOCK_GETTIME_RUNTIME) {
    1913          /* pass: ^^^ cannot use '!' here */
    1914      } else {
    1915          PyObject* dct = PyModule_GetDict(module);
    1916          if (dct == NULL) {
    1917              return -1;
    1918          }
    1919  
    1920          if (PyDict_DelItemString(dct, "clock_gettime") == -1) {
    1921              PyErr_Clear();
    1922          }
    1923          if (PyDict_DelItemString(dct, "clock_gettime_ns") == -1) {
    1924              PyErr_Clear();
    1925          }
    1926          if (PyDict_DelItemString(dct, "clock_settime") == -1) {
    1927              PyErr_Clear();
    1928          }
    1929          if (PyDict_DelItemString(dct, "clock_settime_ns") == -1) {
    1930              PyErr_Clear();
    1931          }
    1932          if (PyDict_DelItemString(dct, "clock_getres") == -1) {
    1933              PyErr_Clear();
    1934          }
    1935      }
    1936  #endif
    1937  #if defined(__APPLE__) && defined(HAVE_THREAD_TIME)
    1938      if (HAVE_CLOCK_GETTIME_RUNTIME) {
    1939          /* pass: ^^^ cannot use '!' here */
    1940      } else {
    1941          PyObject* dct = PyModule_GetDict(module);
    1942  
    1943          if (PyDict_DelItemString(dct, "thread_time") == -1) {
    1944              PyErr_Clear();
    1945          }
    1946          if (PyDict_DelItemString(dct, "thread_time_ns") == -1) {
    1947              PyErr_Clear();
    1948          }
    1949      }
    1950  #endif
    1951      /* Set, or reset, module variables like time.timezone */
    1952      if (init_timezone(module) < 0) {
    1953          return -1;
    1954      }
    1955  
    1956  #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES)
    1957      if (HAVE_CLOCK_GETTIME_RUNTIME) {
    1958  
    1959  #ifdef CLOCK_REALTIME
    1960          if (PyModule_AddIntMacro(module, CLOCK_REALTIME) < 0) {
    1961              return -1;
    1962          }
    1963  #endif
    1964  
    1965  #ifdef CLOCK_MONOTONIC
    1966  
    1967          if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC) < 0) {
    1968              return -1;
    1969          }
    1970  
    1971  #endif
    1972  #ifdef CLOCK_MONOTONIC_RAW
    1973          if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW) < 0) {
    1974              return -1;
    1975          }
    1976  #endif
    1977  
    1978  #ifdef CLOCK_HIGHRES
    1979          if (PyModule_AddIntMacro(module, CLOCK_HIGHRES) < 0) {
    1980              return -1;
    1981          }
    1982  #endif
    1983  #ifdef CLOCK_PROCESS_CPUTIME_ID
    1984          if (PyModule_AddIntMacro(module, CLOCK_PROCESS_CPUTIME_ID) < 0) {
    1985              return -1;
    1986          }
    1987  #endif
    1988  
    1989  #ifdef CLOCK_THREAD_CPUTIME_ID
    1990          if (PyModule_AddIntMacro(module, CLOCK_THREAD_CPUTIME_ID) < 0) {
    1991              return -1;
    1992          }
    1993  #endif
    1994  #ifdef CLOCK_PROF
    1995          if (PyModule_AddIntMacro(module, CLOCK_PROF) < 0) {
    1996              return -1;
    1997          }
    1998  #endif
    1999  #ifdef CLOCK_BOOTTIME
    2000          if (PyModule_AddIntMacro(module, CLOCK_BOOTTIME) < 0) {
    2001              return -1;
    2002          }
    2003  #endif
    2004  #ifdef CLOCK_TAI
    2005          if (PyModule_AddIntMacro(module, CLOCK_TAI) < 0) {
    2006              return -1;
    2007          }
    2008  #endif
    2009  #ifdef CLOCK_UPTIME
    2010          if (PyModule_AddIntMacro(module, CLOCK_UPTIME) < 0) {
    2011              return -1;
    2012          }
    2013  #endif
    2014  #ifdef CLOCK_UPTIME_RAW
    2015  
    2016          if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW) < 0) {
    2017              return -1;
    2018          }
    2019  #endif
    2020      }
    2021  
    2022  #endif  /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */
    2023  
    2024      if (PyModule_AddIntConstant(module, "_STRUCT_TM_ITEMS", 11)) {
    2025          return -1;
    2026      }
    2027  
    2028      // struct_time type
    2029      state->struct_time_type = PyStructSequence_NewType(&struct_time_type_desc);
    2030      if (state->struct_time_type == NULL) {
    2031          return -1;
    2032      }
    2033      if (PyModule_AddType(module, state->struct_time_type)) {
    2034          return -1;
    2035      }
    2036  
    2037  #if defined(__linux__) && !defined(__GLIBC__)
    2038      struct tm tm;
    2039      const time_t zero = 0;
    2040      if (gmtime_r(&zero, &tm) != NULL)
    2041          utc_string = tm.tm_zone;
    2042  #endif
    2043  
    2044  #if defined(MS_WINDOWS)
    2045      if (timer_flags == (DWORD)-1) {
    2046          DWORD test_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
    2047          HANDLE timer = CreateWaitableTimerExW(NULL, NULL, test_flags,
    2048                                                TIMER_ALL_ACCESS);
    2049          if (timer == NULL) {
    2050              // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is not supported.
    2051              timer_flags = 0;
    2052          }
    2053          else {
    2054              // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is supported.
    2055              timer_flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
    2056              CloseHandle(timer);
    2057          }
    2058      }
    2059  #endif
    2060  
    2061      return 0;
    2062  }
    2063  
    2064  
    2065  static int
    2066  time_module_traverse(PyObject *module, visitproc visit, void *arg)
    2067  {
    2068      time_module_state *state = get_time_state(module);
    2069      Py_VISIT(state->struct_time_type);
    2070      return 0;
    2071  }
    2072  
    2073  
    2074  static int
    2075  time_module_clear(PyObject *module)
    2076  {
    2077      time_module_state *state = get_time_state(module);
    2078      Py_CLEAR(state->struct_time_type);
    2079      return 0;
    2080  }
    2081  
    2082  
    2083  static void
    2084  time_module_free(void *module)
    2085  {
    2086      time_module_clear((PyObject *)module);
    2087  }
    2088  
    2089  
    2090  static struct PyModuleDef_Slot time_slots[] = {
    2091      {Py_mod_exec, time_exec},
    2092      {0, NULL}
    2093  };
    2094  
    2095  static struct PyModuleDef timemodule = {
    2096      PyModuleDef_HEAD_INIT,
    2097      .m_name = "time",
    2098      .m_doc = module_doc,
    2099      .m_size = sizeof(time_module_state),
    2100      .m_methods = time_methods,
    2101      .m_slots = time_slots,
    2102      .m_traverse = time_module_traverse,
    2103      .m_clear = time_module_clear,
    2104      .m_free = time_module_free,
    2105  };
    2106  
    2107  PyMODINIT_FUNC
    2108  PyInit_time(void)
    2109  {
    2110      return PyModuleDef_Init(&timemodule);
    2111  }
    2112  
    2113  
    2114  // time.sleep() implementation.
    2115  // On error, raise an exception and return -1.
    2116  // On success, return 0.
    2117  static int
    2118  pysleep(_PyTime_t timeout)
    2119  {
    2120      assert(timeout >= 0);
    2121  
    2122  #ifndef MS_WINDOWS
    2123  #ifdef HAVE_CLOCK_NANOSLEEP
    2124      struct timespec timeout_abs;
    2125  #elif defined(HAVE_NANOSLEEP)
    2126      struct timespec timeout_ts;
    2127  #else
    2128      struct timeval timeout_tv;
    2129  #endif
    2130      _PyTime_t deadline, monotonic;
    2131      int err = 0;
    2132  
    2133      if (get_monotonic(&monotonic) < 0) {
    2134          return -1;
    2135      }
    2136      deadline = monotonic + timeout;
    2137  #ifdef HAVE_CLOCK_NANOSLEEP
    2138      if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) {
    2139          return -1;
    2140      }
    2141  #endif
    2142  
    2143      do {
    2144  #ifdef HAVE_CLOCK_NANOSLEEP
    2145          // use timeout_abs
    2146  #elif defined(HAVE_NANOSLEEP)
    2147          if (_PyTime_AsTimespec(timeout, &timeout_ts) < 0) {
    2148              return -1;
    2149          }
    2150  #else
    2151          if (_PyTime_AsTimeval(timeout, &timeout_tv, _PyTime_ROUND_CEILING) < 0) {
    2152              return -1;
    2153          }
    2154  #endif
    2155  
    2156          int ret;
    2157          Py_BEGIN_ALLOW_THREADS
    2158  #ifdef HAVE_CLOCK_NANOSLEEP
    2159          ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL);
    2160          err = ret;
    2161  #elif defined(HAVE_NANOSLEEP)
    2162          ret = nanosleep(&timeout_ts, NULL);
    2163          err = errno;
    2164  #else
    2165          ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout_tv);
    2166          err = errno;
    2167  #endif
    2168          Py_END_ALLOW_THREADS
    2169  
    2170          if (ret == 0) {
    2171              break;
    2172          }
    2173  
    2174          if (err != EINTR) {
    2175              errno = err;
    2176              PyErr_SetFromErrno(PyExc_OSError);
    2177              return -1;
    2178          }
    2179  
    2180          /* sleep was interrupted by SIGINT */
    2181          if (PyErr_CheckSignals()) {
    2182              return -1;
    2183          }
    2184  
    2185  #ifndef HAVE_CLOCK_NANOSLEEP
    2186          if (get_monotonic(&monotonic) < 0) {
    2187              return -1;
    2188          }
    2189          timeout = deadline - monotonic;
    2190          if (timeout < 0) {
    2191              break;
    2192          }
    2193          /* retry with the recomputed delay */
    2194  #endif
    2195      } while (1);
    2196  
    2197      return 0;
    2198  #else  // MS_WINDOWS
    2199      _PyTime_t timeout_100ns = _PyTime_As100Nanoseconds(timeout,
    2200                                                         _PyTime_ROUND_CEILING);
    2201  
    2202      // Maintain Windows Sleep() semantics for time.sleep(0)
    2203      if (timeout_100ns == 0) {
    2204          Py_BEGIN_ALLOW_THREADS
    2205          // A value of zero causes the thread to relinquish the remainder of its
    2206          // time slice to any other thread that is ready to run. If there are no
    2207          // other threads ready to run, the function returns immediately, and
    2208          // the thread continues execution.
    2209          Sleep(0);
    2210          Py_END_ALLOW_THREADS
    2211          return 0;
    2212      }
    2213  
    2214      LARGE_INTEGER relative_timeout;
    2215      // No need to check for integer overflow, both types are signed
    2216      assert(sizeof(relative_timeout) == sizeof(timeout_100ns));
    2217      // SetWaitableTimer(): a negative due time indicates relative time
    2218      relative_timeout.QuadPart = -timeout_100ns;
    2219  
    2220      HANDLE timer = CreateWaitableTimerExW(NULL, NULL, timer_flags,
    2221                                            TIMER_ALL_ACCESS);
    2222      if (timer == NULL) {
    2223          PyErr_SetFromWindowsErr(0);
    2224          return -1;
    2225      }
    2226  
    2227      if (!SetWaitableTimerEx(timer, &relative_timeout,
    2228                              0, // no period; the timer is signaled once
    2229                              NULL, NULL, // no completion routine
    2230                              NULL,  // no wake context; do not resume from suspend
    2231                              0)) // no tolerable delay for timer coalescing
    2232      {
    2233          PyErr_SetFromWindowsErr(0);
    2234          goto error;
    2235      }
    2236  
    2237      // Only the main thread can be interrupted by SIGINT.
    2238      // Signal handlers are only executed in the main thread.
    2239      if (_PyOS_IsMainThread()) {
    2240          HANDLE sigint_event = _PyOS_SigintEvent();
    2241  
    2242          while (1) {
    2243              // Check for pending SIGINT signal before resetting the event
    2244              if (PyErr_CheckSignals()) {
    2245                  goto error;
    2246              }
    2247              ResetEvent(sigint_event);
    2248  
    2249              HANDLE events[] = {timer, sigint_event};
    2250              DWORD rc;
    2251  
    2252              Py_BEGIN_ALLOW_THREADS
    2253              rc = WaitForMultipleObjects(Py_ARRAY_LENGTH(events), events,
    2254                                          // bWaitAll
    2255                                          FALSE,
    2256                                          // No wait timeout
    2257                                          INFINITE);
    2258              Py_END_ALLOW_THREADS
    2259  
    2260              if (rc == WAIT_FAILED) {
    2261                  PyErr_SetFromWindowsErr(0);
    2262                  goto error;
    2263              }
    2264  
    2265              if (rc == WAIT_OBJECT_0) {
    2266                  // Timer signaled: we are done
    2267                  break;
    2268              }
    2269  
    2270              assert(rc == (WAIT_OBJECT_0 + 1));
    2271              // The sleep was interrupted by SIGINT: restart sleeping
    2272          }
    2273      }
    2274      else {
    2275          DWORD rc;
    2276  
    2277          Py_BEGIN_ALLOW_THREADS
    2278          rc = WaitForSingleObject(timer, INFINITE);
    2279          Py_END_ALLOW_THREADS
    2280  
    2281          if (rc == WAIT_FAILED) {
    2282              PyErr_SetFromWindowsErr(0);
    2283              goto error;
    2284          }
    2285  
    2286          assert(rc == WAIT_OBJECT_0);
    2287          // Timer signaled: we are done
    2288      }
    2289  
    2290      CloseHandle(timer);
    2291      return 0;
    2292  
    2293  error:
    2294      CloseHandle(timer);
    2295      return -1;
    2296  #endif
    2297  }