(root)/
Python-3.11.7/
Lib/
test/
test_time.py
       1  from test import support
       2  from test.support import warnings_helper
       3  import decimal
       4  import enum
       5  import locale
       6  import math
       7  import platform
       8  import sys
       9  import sysconfig
      10  import time
      11  import threading
      12  import unittest
      13  try:
      14      import _testcapi
      15  except ImportError:
      16      _testcapi = None
      17  
      18  from test.support import skip_if_buggy_ucrt_strfptime
      19  
      20  # Max year is only limited by the size of C int.
      21  SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4
      22  TIME_MAXYEAR = (1 << 8 * SIZEOF_INT - 1) - 1
      23  TIME_MINYEAR = -TIME_MAXYEAR - 1 + 1900
      24  
      25  SEC_TO_US = 10 ** 6
      26  US_TO_NS = 10 ** 3
      27  MS_TO_NS = 10 ** 6
      28  SEC_TO_NS = 10 ** 9
      29  NS_TO_SEC = 10 ** 9
      30  
      31  class ESC[4;38;5;81m_PyTime(ESC[4;38;5;149menumESC[4;38;5;149m.ESC[4;38;5;149mIntEnum):
      32      # Round towards minus infinity (-inf)
      33      ROUND_FLOOR = 0
      34      # Round towards infinity (+inf)
      35      ROUND_CEILING = 1
      36      # Round to nearest with ties going to nearest even integer
      37      ROUND_HALF_EVEN = 2
      38      # Round away from zero
      39      ROUND_UP = 3
      40  
      41  # _PyTime_t is int64_t
      42  _PyTime_MIN = -2 ** 63
      43  _PyTime_MAX = 2 ** 63 - 1
      44  
      45  # Rounding modes supported by PyTime
      46  ROUNDING_MODES = (
      47      # (PyTime rounding method, decimal rounding method)
      48      (_PyTime.ROUND_FLOOR, decimal.ROUND_FLOOR),
      49      (_PyTime.ROUND_CEILING, decimal.ROUND_CEILING),
      50      (_PyTime.ROUND_HALF_EVEN, decimal.ROUND_HALF_EVEN),
      51      (_PyTime.ROUND_UP, decimal.ROUND_UP),
      52  )
      53  
      54  
      55  class ESC[4;38;5;81mTimeTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      56  
      57      def setUp(self):
      58          self.t = time.time()
      59  
      60      def test_data_attributes(self):
      61          time.altzone
      62          time.daylight
      63          time.timezone
      64          time.tzname
      65  
      66      def test_time(self):
      67          time.time()
      68          info = time.get_clock_info('time')
      69          self.assertFalse(info.monotonic)
      70          self.assertTrue(info.adjustable)
      71  
      72      def test_time_ns_type(self):
      73          def check_ns(sec, ns):
      74              self.assertIsInstance(ns, int)
      75  
      76              sec_ns = int(sec * 1e9)
      77              # tolerate a difference of 50 ms
      78              self.assertLess((sec_ns - ns), 50 ** 6, (sec, ns))
      79  
      80          check_ns(time.time(),
      81                   time.time_ns())
      82          check_ns(time.monotonic(),
      83                   time.monotonic_ns())
      84          check_ns(time.perf_counter(),
      85                   time.perf_counter_ns())
      86          check_ns(time.process_time(),
      87                   time.process_time_ns())
      88  
      89          if hasattr(time, 'thread_time'):
      90              check_ns(time.thread_time(),
      91                       time.thread_time_ns())
      92  
      93          if hasattr(time, 'clock_gettime'):
      94              check_ns(time.clock_gettime(time.CLOCK_REALTIME),
      95                       time.clock_gettime_ns(time.CLOCK_REALTIME))
      96  
      97      @unittest.skipUnless(hasattr(time, 'clock_gettime'),
      98                           'need time.clock_gettime()')
      99      def test_clock_realtime(self):
     100          t = time.clock_gettime(time.CLOCK_REALTIME)
     101          self.assertIsInstance(t, float)
     102  
     103      @unittest.skipUnless(hasattr(time, 'clock_gettime'),
     104                           'need time.clock_gettime()')
     105      @unittest.skipUnless(hasattr(time, 'CLOCK_MONOTONIC'),
     106                           'need time.CLOCK_MONOTONIC')
     107      def test_clock_monotonic(self):
     108          a = time.clock_gettime(time.CLOCK_MONOTONIC)
     109          b = time.clock_gettime(time.CLOCK_MONOTONIC)
     110          self.assertLessEqual(a, b)
     111  
     112      @unittest.skipUnless(hasattr(time, 'pthread_getcpuclockid'),
     113                           'need time.pthread_getcpuclockid()')
     114      @unittest.skipUnless(hasattr(time, 'clock_gettime'),
     115                           'need time.clock_gettime()')
     116      def test_pthread_getcpuclockid(self):
     117          clk_id = time.pthread_getcpuclockid(threading.get_ident())
     118          self.assertTrue(type(clk_id) is int)
     119          # when in 32-bit mode AIX only returns the predefined constant
     120          if platform.system() == "AIX" and (sys.maxsize.bit_length() <= 32):
     121              self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
     122          # Solaris returns CLOCK_THREAD_CPUTIME_ID when current thread is given
     123          elif sys.platform.startswith("sunos"):
     124              self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
     125          else:
     126              self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID)
     127          t1 = time.clock_gettime(clk_id)
     128          t2 = time.clock_gettime(clk_id)
     129          self.assertLessEqual(t1, t2)
     130  
     131      @unittest.skipUnless(hasattr(time, 'clock_getres'),
     132                           'need time.clock_getres()')
     133      def test_clock_getres(self):
     134          res = time.clock_getres(time.CLOCK_REALTIME)
     135          self.assertGreater(res, 0.0)
     136          self.assertLessEqual(res, 1.0)
     137  
     138      @unittest.skipUnless(hasattr(time, 'clock_settime'),
     139                           'need time.clock_settime()')
     140      def test_clock_settime(self):
     141          t = time.clock_gettime(time.CLOCK_REALTIME)
     142          try:
     143              time.clock_settime(time.CLOCK_REALTIME, t)
     144          except PermissionError:
     145              pass
     146  
     147          if hasattr(time, 'CLOCK_MONOTONIC'):
     148              self.assertRaises(OSError,
     149                                time.clock_settime, time.CLOCK_MONOTONIC, 0)
     150  
     151      def test_conversions(self):
     152          self.assertEqual(time.ctime(self.t),
     153                           time.asctime(time.localtime(self.t)))
     154          self.assertEqual(int(time.mktime(time.localtime(self.t))),
     155                           int(self.t))
     156  
     157      def test_sleep(self):
     158          self.assertRaises(ValueError, time.sleep, -2)
     159          self.assertRaises(ValueError, time.sleep, -1)
     160          time.sleep(1.2)
     161  
     162      def test_epoch(self):
     163          # bpo-43869: Make sure that Python use the same Epoch on all platforms:
     164          # January 1, 1970, 00:00:00 (UTC).
     165          epoch = time.gmtime(0)
     166          # Only test the date and time, ignore other gmtime() members
     167          self.assertEqual(tuple(epoch)[:6], (1970, 1, 1, 0, 0, 0), epoch)
     168  
     169      def test_strftime(self):
     170          tt = time.gmtime(self.t)
     171          for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
     172                            'j', 'm', 'M', 'p', 'S',
     173                            'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
     174              format = ' %' + directive
     175              try:
     176                  time.strftime(format, tt)
     177              except ValueError:
     178                  self.fail('conversion specifier: %r failed.' % format)
     179  
     180          self.assertRaises(TypeError, time.strftime, b'%S', tt)
     181          # embedded null character
     182          self.assertRaises(ValueError, time.strftime, '%S\0', tt)
     183  
     184      def _bounds_checking(self, func):
     185          # Make sure that strftime() checks the bounds of the various parts
     186          # of the time tuple (0 is valid for *all* values).
     187  
     188          # The year field is tested by other test cases above
     189  
     190          # Check month [1, 12] + zero support
     191          func((1900, 0, 1, 0, 0, 0, 0, 1, -1))
     192          func((1900, 12, 1, 0, 0, 0, 0, 1, -1))
     193          self.assertRaises(ValueError, func,
     194                              (1900, -1, 1, 0, 0, 0, 0, 1, -1))
     195          self.assertRaises(ValueError, func,
     196                              (1900, 13, 1, 0, 0, 0, 0, 1, -1))
     197          # Check day of month [1, 31] + zero support
     198          func((1900, 1, 0, 0, 0, 0, 0, 1, -1))
     199          func((1900, 1, 31, 0, 0, 0, 0, 1, -1))
     200          self.assertRaises(ValueError, func,
     201                              (1900, 1, -1, 0, 0, 0, 0, 1, -1))
     202          self.assertRaises(ValueError, func,
     203                              (1900, 1, 32, 0, 0, 0, 0, 1, -1))
     204          # Check hour [0, 23]
     205          func((1900, 1, 1, 23, 0, 0, 0, 1, -1))
     206          self.assertRaises(ValueError, func,
     207                              (1900, 1, 1, -1, 0, 0, 0, 1, -1))
     208          self.assertRaises(ValueError, func,
     209                              (1900, 1, 1, 24, 0, 0, 0, 1, -1))
     210          # Check minute [0, 59]
     211          func((1900, 1, 1, 0, 59, 0, 0, 1, -1))
     212          self.assertRaises(ValueError, func,
     213                              (1900, 1, 1, 0, -1, 0, 0, 1, -1))
     214          self.assertRaises(ValueError, func,
     215                              (1900, 1, 1, 0, 60, 0, 0, 1, -1))
     216          # Check second [0, 61]
     217          self.assertRaises(ValueError, func,
     218                              (1900, 1, 1, 0, 0, -1, 0, 1, -1))
     219          # C99 only requires allowing for one leap second, but Python's docs say
     220          # allow two leap seconds (0..61)
     221          func((1900, 1, 1, 0, 0, 60, 0, 1, -1))
     222          func((1900, 1, 1, 0, 0, 61, 0, 1, -1))
     223          self.assertRaises(ValueError, func,
     224                              (1900, 1, 1, 0, 0, 62, 0, 1, -1))
     225          # No check for upper-bound day of week;
     226          #  value forced into range by a ``% 7`` calculation.
     227          # Start check at -2 since gettmarg() increments value before taking
     228          #  modulo.
     229          self.assertEqual(func((1900, 1, 1, 0, 0, 0, -1, 1, -1)),
     230                           func((1900, 1, 1, 0, 0, 0, +6, 1, -1)))
     231          self.assertRaises(ValueError, func,
     232                              (1900, 1, 1, 0, 0, 0, -2, 1, -1))
     233          # Check day of the year [1, 366] + zero support
     234          func((1900, 1, 1, 0, 0, 0, 0, 0, -1))
     235          func((1900, 1, 1, 0, 0, 0, 0, 366, -1))
     236          self.assertRaises(ValueError, func,
     237                              (1900, 1, 1, 0, 0, 0, 0, -1, -1))
     238          self.assertRaises(ValueError, func,
     239                              (1900, 1, 1, 0, 0, 0, 0, 367, -1))
     240  
     241      def test_strftime_bounding_check(self):
     242          self._bounds_checking(lambda tup: time.strftime('', tup))
     243  
     244      def test_strftime_format_check(self):
     245          # Test that strftime does not crash on invalid format strings
     246          # that may trigger a buffer overread. When not triggered,
     247          # strftime may succeed or raise ValueError depending on
     248          # the platform.
     249          for x in [ '', 'A', '%A', '%AA' ]:
     250              for y in range(0x0, 0x10):
     251                  for z in [ '%', 'A%', 'AA%', '%A%', 'A%A%', '%#' ]:
     252                      try:
     253                          time.strftime(x * y + z)
     254                      except ValueError:
     255                          pass
     256  
     257      def test_default_values_for_zero(self):
     258          # Make sure that using all zeros uses the proper default
     259          # values.  No test for daylight savings since strftime() does
     260          # not change output based on its value and no test for year
     261          # because systems vary in their support for year 0.
     262          expected = "2000 01 01 00 00 00 1 001"
     263          with warnings_helper.check_warnings():
     264              result = time.strftime("%Y %m %d %H %M %S %w %j", (2000,)+(0,)*8)
     265          self.assertEqual(expected, result)
     266  
     267      @skip_if_buggy_ucrt_strfptime
     268      def test_strptime(self):
     269          # Should be able to go round-trip from strftime to strptime without
     270          # raising an exception.
     271          tt = time.gmtime(self.t)
     272          for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
     273                            'j', 'm', 'M', 'p', 'S',
     274                            'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
     275              format = '%' + directive
     276              strf_output = time.strftime(format, tt)
     277              try:
     278                  time.strptime(strf_output, format)
     279              except ValueError:
     280                  self.fail("conversion specifier %r failed with '%s' input." %
     281                            (format, strf_output))
     282  
     283      def test_strptime_bytes(self):
     284          # Make sure only strings are accepted as arguments to strptime.
     285          self.assertRaises(TypeError, time.strptime, b'2009', "%Y")
     286          self.assertRaises(TypeError, time.strptime, '2009', b'%Y')
     287  
     288      def test_strptime_exception_context(self):
     289          # check that this doesn't chain exceptions needlessly (see #17572)
     290          with self.assertRaises(ValueError) as e:
     291              time.strptime('', '%D')
     292          self.assertIs(e.exception.__suppress_context__, True)
     293          # additional check for IndexError branch (issue #19545)
     294          with self.assertRaises(ValueError) as e:
     295              time.strptime('19', '%Y %')
     296          self.assertIs(e.exception.__suppress_context__, True)
     297  
     298      def test_asctime(self):
     299          time.asctime(time.gmtime(self.t))
     300  
     301          # Max year is only limited by the size of C int.
     302          for bigyear in TIME_MAXYEAR, TIME_MINYEAR:
     303              asc = time.asctime((bigyear, 6, 1) + (0,) * 6)
     304              self.assertEqual(asc[-len(str(bigyear)):], str(bigyear))
     305          self.assertRaises(OverflowError, time.asctime,
     306                            (TIME_MAXYEAR + 1,) + (0,) * 8)
     307          self.assertRaises(OverflowError, time.asctime,
     308                            (TIME_MINYEAR - 1,) + (0,) * 8)
     309          self.assertRaises(TypeError, time.asctime, 0)
     310          self.assertRaises(TypeError, time.asctime, ())
     311          self.assertRaises(TypeError, time.asctime, (0,) * 10)
     312  
     313      def test_asctime_bounding_check(self):
     314          self._bounds_checking(time.asctime)
     315  
     316      @unittest.skipIf(
     317          support.is_emscripten, "musl libc issue on Emscripten, bpo-46390"
     318      )
     319      def test_ctime(self):
     320          t = time.mktime((1973, 9, 16, 1, 3, 52, 0, 0, -1))
     321          self.assertEqual(time.ctime(t), 'Sun Sep 16 01:03:52 1973')
     322          t = time.mktime((2000, 1, 1, 0, 0, 0, 0, 0, -1))
     323          self.assertEqual(time.ctime(t), 'Sat Jan  1 00:00:00 2000')
     324          for year in [-100, 100, 1000, 2000, 2050, 10000]:
     325              try:
     326                  testval = time.mktime((year, 1, 10) + (0,)*6)
     327              except (ValueError, OverflowError):
     328                  # If mktime fails, ctime will fail too.  This may happen
     329                  # on some platforms.
     330                  pass
     331              else:
     332                  self.assertEqual(time.ctime(testval)[20:], str(year))
     333  
     334      @unittest.skipUnless(hasattr(time, "tzset"),
     335                           "time module has no attribute tzset")
     336      def test_tzset(self):
     337  
     338          from os import environ
     339  
     340          # Epoch time of midnight Dec 25th 2002. Never DST in northern
     341          # hemisphere.
     342          xmas2002 = 1040774400.0
     343  
     344          # These formats are correct for 2002, and possibly future years
     345          # This format is the 'standard' as documented at:
     346          # http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap08.html
     347          # They are also documented in the tzset(3) man page on most Unix
     348          # systems.
     349          eastern = 'EST+05EDT,M4.1.0,M10.5.0'
     350          victoria = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
     351          utc='UTC+0'
     352  
     353          org_TZ = environ.get('TZ',None)
     354          try:
     355              # Make sure we can switch to UTC time and results are correct
     356              # Note that unknown timezones default to UTC.
     357              # Note that altzone is undefined in UTC, as there is no DST
     358              environ['TZ'] = eastern
     359              time.tzset()
     360              environ['TZ'] = utc
     361              time.tzset()
     362              self.assertEqual(
     363                  time.gmtime(xmas2002), time.localtime(xmas2002)
     364                  )
     365              self.assertEqual(time.daylight, 0)
     366              self.assertEqual(time.timezone, 0)
     367              self.assertEqual(time.localtime(xmas2002).tm_isdst, 0)
     368  
     369              # Make sure we can switch to US/Eastern
     370              environ['TZ'] = eastern
     371              time.tzset()
     372              self.assertNotEqual(time.gmtime(xmas2002), time.localtime(xmas2002))
     373              self.assertEqual(time.tzname, ('EST', 'EDT'))
     374              self.assertEqual(len(time.tzname), 2)
     375              self.assertEqual(time.daylight, 1)
     376              self.assertEqual(time.timezone, 18000)
     377              self.assertEqual(time.altzone, 14400)
     378              self.assertEqual(time.localtime(xmas2002).tm_isdst, 0)
     379              self.assertEqual(len(time.tzname), 2)
     380  
     381              # Now go to the southern hemisphere.
     382              environ['TZ'] = victoria
     383              time.tzset()
     384              self.assertNotEqual(time.gmtime(xmas2002), time.localtime(xmas2002))
     385  
     386              # Issue #11886: Australian Eastern Standard Time (UTC+10) is called
     387              # "EST" (as Eastern Standard Time, UTC-5) instead of "AEST"
     388              # (non-DST timezone), and "EDT" instead of "AEDT" (DST timezone),
     389              # on some operating systems (e.g. FreeBSD), which is wrong. See for
     390              # example this bug:
     391              # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=93810
     392              self.assertIn(time.tzname[0], ('AEST' 'EST'), time.tzname[0])
     393              self.assertTrue(time.tzname[1] in ('AEDT', 'EDT'), str(time.tzname[1]))
     394              self.assertEqual(len(time.tzname), 2)
     395              self.assertEqual(time.daylight, 1)
     396              self.assertEqual(time.timezone, -36000)
     397              self.assertEqual(time.altzone, -39600)
     398              self.assertEqual(time.localtime(xmas2002).tm_isdst, 1)
     399  
     400          finally:
     401              # Repair TZ environment variable in case any other tests
     402              # rely on it.
     403              if org_TZ is not None:
     404                  environ['TZ'] = org_TZ
     405              elif 'TZ' in environ:
     406                  del environ['TZ']
     407              time.tzset()
     408  
     409      def test_insane_timestamps(self):
     410          # It's possible that some platform maps time_t to double,
     411          # and that this test will fail there.  This test should
     412          # exempt such platforms (provided they return reasonable
     413          # results!).
     414          for func in time.ctime, time.gmtime, time.localtime:
     415              for unreasonable in -1e200, 1e200:
     416                  self.assertRaises(OverflowError, func, unreasonable)
     417  
     418      def test_ctime_without_arg(self):
     419          # Not sure how to check the values, since the clock could tick
     420          # at any time.  Make sure these are at least accepted and
     421          # don't raise errors.
     422          time.ctime()
     423          time.ctime(None)
     424  
     425      def test_gmtime_without_arg(self):
     426          gt0 = time.gmtime()
     427          gt1 = time.gmtime(None)
     428          t0 = time.mktime(gt0)
     429          t1 = time.mktime(gt1)
     430          self.assertAlmostEqual(t1, t0, delta=0.2)
     431  
     432      def test_localtime_without_arg(self):
     433          lt0 = time.localtime()
     434          lt1 = time.localtime(None)
     435          t0 = time.mktime(lt0)
     436          t1 = time.mktime(lt1)
     437          self.assertAlmostEqual(t1, t0, delta=0.2)
     438  
     439      def test_mktime(self):
     440          # Issue #1726687
     441          for t in (-2, -1, 0, 1):
     442              try:
     443                  tt = time.localtime(t)
     444              except (OverflowError, OSError):
     445                  pass
     446              else:
     447                  self.assertEqual(time.mktime(tt), t)
     448  
     449      # Issue #13309: passing extreme values to mktime() or localtime()
     450      # borks the glibc's internal timezone data.
     451      @unittest.skipUnless(platform.libc_ver()[0] != 'glibc',
     452                           "disabled because of a bug in glibc. Issue #13309")
     453      def test_mktime_error(self):
     454          # It may not be possible to reliably make mktime return an error
     455          # on all platforms.  This will make sure that no other exception
     456          # than OverflowError is raised for an extreme value.
     457          tt = time.gmtime(self.t)
     458          tzname = time.strftime('%Z', tt)
     459          self.assertNotEqual(tzname, 'LMT')
     460          try:
     461              time.mktime((-1, 1, 1, 0, 0, 0, -1, -1, -1))
     462          except OverflowError:
     463              pass
     464          self.assertEqual(time.strftime('%Z', tt), tzname)
     465  
     466      def test_monotonic(self):
     467          # monotonic() should not go backward
     468          times = [time.monotonic() for n in range(100)]
     469          t1 = times[0]
     470          for t2 in times[1:]:
     471              self.assertGreaterEqual(t2, t1, "times=%s" % times)
     472              t1 = t2
     473  
     474          # monotonic() includes time elapsed during a sleep
     475          t1 = time.monotonic()
     476          time.sleep(0.5)
     477          t2 = time.monotonic()
     478          dt = t2 - t1
     479          self.assertGreater(t2, t1)
     480          # bpo-20101: tolerate a difference of 50 ms because of bad timer
     481          # resolution on Windows
     482          self.assertTrue(0.450 <= dt)
     483  
     484          # monotonic() is a monotonic but non adjustable clock
     485          info = time.get_clock_info('monotonic')
     486          self.assertTrue(info.monotonic)
     487          self.assertFalse(info.adjustable)
     488  
     489      def test_perf_counter(self):
     490          time.perf_counter()
     491  
     492      @unittest.skipIf(
     493          support.is_wasi, "process_time not available on WASI"
     494      )
     495      def test_process_time(self):
     496          # process_time() should not include time spend during a sleep
     497          start = time.process_time()
     498          time.sleep(0.100)
     499          stop = time.process_time()
     500          # use 20 ms because process_time() has usually a resolution of 15 ms
     501          # on Windows
     502          self.assertLess(stop - start, 0.020)
     503  
     504          info = time.get_clock_info('process_time')
     505          self.assertTrue(info.monotonic)
     506          self.assertFalse(info.adjustable)
     507  
     508      def test_thread_time(self):
     509          if not hasattr(time, 'thread_time'):
     510              if sys.platform.startswith(('linux', 'win')):
     511                  self.fail("time.thread_time() should be available on %r"
     512                            % (sys.platform,))
     513              else:
     514                  self.skipTest("need time.thread_time")
     515  
     516          # thread_time() should not include time spend during a sleep
     517          start = time.thread_time()
     518          time.sleep(0.100)
     519          stop = time.thread_time()
     520          # use 20 ms because thread_time() has usually a resolution of 15 ms
     521          # on Windows
     522          self.assertLess(stop - start, 0.020)
     523  
     524          info = time.get_clock_info('thread_time')
     525          self.assertTrue(info.monotonic)
     526          self.assertFalse(info.adjustable)
     527  
     528      @unittest.skipUnless(hasattr(time, 'clock_settime'),
     529                           'need time.clock_settime')
     530      def test_monotonic_settime(self):
     531          t1 = time.monotonic()
     532          realtime = time.clock_gettime(time.CLOCK_REALTIME)
     533          # jump backward with an offset of 1 hour
     534          try:
     535              time.clock_settime(time.CLOCK_REALTIME, realtime - 3600)
     536          except PermissionError as err:
     537              self.skipTest(err)
     538          t2 = time.monotonic()
     539          time.clock_settime(time.CLOCK_REALTIME, realtime)
     540          # monotonic must not be affected by system clock updates
     541          self.assertGreaterEqual(t2, t1)
     542  
     543      def test_localtime_failure(self):
     544          # Issue #13847: check for localtime() failure
     545          invalid_time_t = None
     546          for time_t in (-1, 2**30, 2**33, 2**60):
     547              try:
     548                  time.localtime(time_t)
     549              except OverflowError:
     550                  self.skipTest("need 64-bit time_t")
     551              except OSError:
     552                  invalid_time_t = time_t
     553                  break
     554          if invalid_time_t is None:
     555              self.skipTest("unable to find an invalid time_t value")
     556  
     557          self.assertRaises(OSError, time.localtime, invalid_time_t)
     558          self.assertRaises(OSError, time.ctime, invalid_time_t)
     559  
     560          # Issue #26669: check for localtime() failure
     561          self.assertRaises(ValueError, time.localtime, float("nan"))
     562          self.assertRaises(ValueError, time.ctime, float("nan"))
     563  
     564      def test_get_clock_info(self):
     565          clocks = [
     566              'monotonic',
     567              'perf_counter',
     568              'process_time',
     569              'time',
     570          ]
     571          if hasattr(time, 'thread_time'):
     572              clocks.append('thread_time')
     573  
     574          for name in clocks:
     575              with self.subTest(name=name):
     576                  info = time.get_clock_info(name)
     577  
     578                  self.assertIsInstance(info.implementation, str)
     579                  self.assertNotEqual(info.implementation, '')
     580                  self.assertIsInstance(info.monotonic, bool)
     581                  self.assertIsInstance(info.resolution, float)
     582                  # 0.0 < resolution <= 1.0
     583                  self.assertGreater(info.resolution, 0.0)
     584                  self.assertLessEqual(info.resolution, 1.0)
     585                  self.assertIsInstance(info.adjustable, bool)
     586  
     587          self.assertRaises(ValueError, time.get_clock_info, 'xxx')
     588  
     589  
     590  class ESC[4;38;5;81mTestLocale(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     591      def setUp(self):
     592          self.oldloc = locale.setlocale(locale.LC_ALL)
     593  
     594      def tearDown(self):
     595          locale.setlocale(locale.LC_ALL, self.oldloc)
     596  
     597      def test_bug_3061(self):
     598          try:
     599              tmp = locale.setlocale(locale.LC_ALL, "fr_FR")
     600          except locale.Error:
     601              self.skipTest('could not set locale.LC_ALL to fr_FR')
     602          # This should not cause an exception
     603          time.strftime("%B", (2009,2,1,0,0,0,0,0,0))
     604  
     605  
     606  class ESC[4;38;5;81m_TestAsctimeYear:
     607      _format = '%d'
     608  
     609      def yearstr(self, y):
     610          return time.asctime((y,) + (0,) * 8).split()[-1]
     611  
     612      def test_large_year(self):
     613          # Check that it doesn't crash for year > 9999
     614          self.assertEqual(self.yearstr(12345), '12345')
     615          self.assertEqual(self.yearstr(123456789), '123456789')
     616  
     617  class ESC[4;38;5;81m_TestStrftimeYear:
     618  
     619      # Issue 13305:  For years < 1000, the value is not always
     620      # padded to 4 digits across platforms.  The C standard
     621      # assumes year >= 1900, so it does not specify the number
     622      # of digits.
     623  
     624      if time.strftime('%Y', (1,) + (0,) * 8) == '0001':
     625          _format = '%04d'
     626      else:
     627          _format = '%d'
     628  
     629      def yearstr(self, y):
     630          return time.strftime('%Y', (y,) + (0,) * 8)
     631  
     632      @unittest.skipUnless(
     633          support.has_strftime_extensions, "requires strftime extension"
     634      )
     635      def test_4dyear(self):
     636          # Check that we can return the zero padded value.
     637          if self._format == '%04d':
     638              self.test_year('%04d')
     639          else:
     640              def year4d(y):
     641                  return time.strftime('%4Y', (y,) + (0,) * 8)
     642              self.test_year('%04d', func=year4d)
     643  
     644      def skip_if_not_supported(y):
     645          msg = "strftime() is limited to [1; 9999] with Visual Studio"
     646          # Check that it doesn't crash for year > 9999
     647          try:
     648              time.strftime('%Y', (y,) + (0,) * 8)
     649          except ValueError:
     650              cond = False
     651          else:
     652              cond = True
     653          return unittest.skipUnless(cond, msg)
     654  
     655      @skip_if_not_supported(10000)
     656      def test_large_year(self):
     657          return super().test_large_year()
     658  
     659      @skip_if_not_supported(0)
     660      def test_negative(self):
     661          return super().test_negative()
     662  
     663      del skip_if_not_supported
     664  
     665  
     666  class ESC[4;38;5;81m_Test4dYear:
     667      _format = '%d'
     668  
     669      def test_year(self, fmt=None, func=None):
     670          fmt = fmt or self._format
     671          func = func or self.yearstr
     672          self.assertEqual(func(1),    fmt % 1)
     673          self.assertEqual(func(68),   fmt % 68)
     674          self.assertEqual(func(69),   fmt % 69)
     675          self.assertEqual(func(99),   fmt % 99)
     676          self.assertEqual(func(999),  fmt % 999)
     677          self.assertEqual(func(9999), fmt % 9999)
     678  
     679      def test_large_year(self):
     680          self.assertEqual(self.yearstr(12345).lstrip('+'), '12345')
     681          self.assertEqual(self.yearstr(123456789).lstrip('+'), '123456789')
     682          self.assertEqual(self.yearstr(TIME_MAXYEAR).lstrip('+'), str(TIME_MAXYEAR))
     683          self.assertRaises(OverflowError, self.yearstr, TIME_MAXYEAR + 1)
     684  
     685      def test_negative(self):
     686          self.assertEqual(self.yearstr(-1), self._format % -1)
     687          self.assertEqual(self.yearstr(-1234), '-1234')
     688          self.assertEqual(self.yearstr(-123456), '-123456')
     689          self.assertEqual(self.yearstr(-123456789), str(-123456789))
     690          self.assertEqual(self.yearstr(-1234567890), str(-1234567890))
     691          self.assertEqual(self.yearstr(TIME_MINYEAR), str(TIME_MINYEAR))
     692          # Modules/timemodule.c checks for underflow
     693          self.assertRaises(OverflowError, self.yearstr, TIME_MINYEAR - 1)
     694          with self.assertRaises(OverflowError):
     695              self.yearstr(-TIME_MAXYEAR - 1)
     696  
     697  
     698  class ESC[4;38;5;81mTestAsctime4dyear(ESC[4;38;5;149m_TestAsctimeYear, ESC[4;38;5;149m_Test4dYear, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     699      pass
     700  
     701  class ESC[4;38;5;81mTestStrftime4dyear(ESC[4;38;5;149m_TestStrftimeYear, ESC[4;38;5;149m_Test4dYear, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     702      pass
     703  
     704  
     705  class ESC[4;38;5;81mTestPytime(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     706      @skip_if_buggy_ucrt_strfptime
     707      @unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support")
     708      @unittest.skipIf(
     709          support.is_emscripten, "musl libc issue on Emscripten, bpo-46390"
     710      )
     711      def test_localtime_timezone(self):
     712  
     713          # Get the localtime and examine it for the offset and zone.
     714          lt = time.localtime()
     715          self.assertTrue(hasattr(lt, "tm_gmtoff"))
     716          self.assertTrue(hasattr(lt, "tm_zone"))
     717  
     718          # See if the offset and zone are similar to the module
     719          # attributes.
     720          if lt.tm_gmtoff is None:
     721              self.assertTrue(not hasattr(time, "timezone"))
     722          else:
     723              self.assertEqual(lt.tm_gmtoff, -[time.timezone, time.altzone][lt.tm_isdst])
     724          if lt.tm_zone is None:
     725              self.assertTrue(not hasattr(time, "tzname"))
     726          else:
     727              self.assertEqual(lt.tm_zone, time.tzname[lt.tm_isdst])
     728  
     729          # Try and make UNIX times from the localtime and a 9-tuple
     730          # created from the localtime. Test to see that the times are
     731          # the same.
     732          t = time.mktime(lt); t9 = time.mktime(lt[:9])
     733          self.assertEqual(t, t9)
     734  
     735          # Make localtimes from the UNIX times and compare them to
     736          # the original localtime, thus making a round trip.
     737          new_lt = time.localtime(t); new_lt9 = time.localtime(t9)
     738          self.assertEqual(new_lt, lt)
     739          self.assertEqual(new_lt.tm_gmtoff, lt.tm_gmtoff)
     740          self.assertEqual(new_lt.tm_zone, lt.tm_zone)
     741          self.assertEqual(new_lt9, lt)
     742          self.assertEqual(new_lt.tm_gmtoff, lt.tm_gmtoff)
     743          self.assertEqual(new_lt9.tm_zone, lt.tm_zone)
     744  
     745      @unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support")
     746      def test_strptime_timezone(self):
     747          t = time.strptime("UTC", "%Z")
     748          self.assertEqual(t.tm_zone, 'UTC')
     749          t = time.strptime("+0500", "%z")
     750          self.assertEqual(t.tm_gmtoff, 5 * 3600)
     751  
     752      @unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support")
     753      def test_short_times(self):
     754  
     755          import pickle
     756  
     757          # Load a short time structure using pickle.
     758          st = b"ctime\nstruct_time\np0\n((I2007\nI8\nI11\nI1\nI24\nI49\nI5\nI223\nI1\ntp1\n(dp2\ntp3\nRp4\n."
     759          lt = pickle.loads(st)
     760          self.assertIs(lt.tm_gmtoff, None)
     761          self.assertIs(lt.tm_zone, None)
     762  
     763  
     764  @unittest.skipIf(_testcapi is None, 'need the _testcapi module')
     765  class ESC[4;38;5;81mCPyTimeTestCase:
     766      """
     767      Base class to test the C _PyTime_t API.
     768      """
     769      OVERFLOW_SECONDS = None
     770  
     771      def setUp(self):
     772          from _testcapi import SIZEOF_TIME_T
     773          bits = SIZEOF_TIME_T * 8 - 1
     774          self.time_t_min = -2 ** bits
     775          self.time_t_max = 2 ** bits - 1
     776  
     777      def time_t_filter(self, seconds):
     778          return (self.time_t_min <= seconds <= self.time_t_max)
     779  
     780      def _rounding_values(self, use_float):
     781          "Build timestamps used to test rounding."
     782  
     783          units = [1, US_TO_NS, MS_TO_NS, SEC_TO_NS]
     784          if use_float:
     785              # picoseconds are only tested to pytime_converter accepting floats
     786              units.append(1e-3)
     787  
     788          values = (
     789              # small values
     790              1, 2, 5, 7, 123, 456, 1234,
     791              # 10^k - 1
     792              9,
     793              99,
     794              999,
     795              9999,
     796              99999,
     797              999999,
     798              # test half even rounding near 0.5, 1.5, 2.5, 3.5, 4.5
     799              499, 500, 501,
     800              1499, 1500, 1501,
     801              2500,
     802              3500,
     803              4500,
     804          )
     805  
     806          ns_timestamps = [0]
     807          for unit in units:
     808              for value in values:
     809                  ns = value * unit
     810                  ns_timestamps.extend((-ns, ns))
     811          for pow2 in (0, 5, 10, 15, 22, 23, 24, 30, 33):
     812              ns = (2 ** pow2) * SEC_TO_NS
     813              ns_timestamps.extend((
     814                  -ns-1, -ns, -ns+1,
     815                  ns-1, ns, ns+1
     816              ))
     817          for seconds in (_testcapi.INT_MIN, _testcapi.INT_MAX):
     818              ns_timestamps.append(seconds * SEC_TO_NS)
     819          if use_float:
     820              # numbers with an exact representation in IEEE 754 (base 2)
     821              for pow2 in (3, 7, 10, 15):
     822                  ns = 2.0 ** (-pow2)
     823                  ns_timestamps.extend((-ns, ns))
     824  
     825          # seconds close to _PyTime_t type limit
     826          ns = (2 ** 63 // SEC_TO_NS) * SEC_TO_NS
     827          ns_timestamps.extend((-ns, ns))
     828  
     829          return ns_timestamps
     830  
     831      def _check_rounding(self, pytime_converter, expected_func,
     832                          use_float, unit_to_sec, value_filter=None):
     833  
     834          def convert_values(ns_timestamps):
     835              if use_float:
     836                  unit_to_ns = SEC_TO_NS / float(unit_to_sec)
     837                  values = [ns / unit_to_ns for ns in ns_timestamps]
     838              else:
     839                  unit_to_ns = SEC_TO_NS // unit_to_sec
     840                  values = [ns // unit_to_ns for ns in ns_timestamps]
     841  
     842              if value_filter:
     843                  values = filter(value_filter, values)
     844  
     845              # remove duplicates and sort
     846              return sorted(set(values))
     847  
     848          # test rounding
     849          ns_timestamps = self._rounding_values(use_float)
     850          valid_values = convert_values(ns_timestamps)
     851          for time_rnd, decimal_rnd in ROUNDING_MODES :
     852              with decimal.localcontext() as context:
     853                  context.rounding = decimal_rnd
     854  
     855                  for value in valid_values:
     856                      debug_info = {'value': value, 'rounding': decimal_rnd}
     857                      try:
     858                          result = pytime_converter(value, time_rnd)
     859                          expected = expected_func(value)
     860                      except Exception:
     861                          self.fail("Error on timestamp conversion: %s" % debug_info)
     862                      self.assertEqual(result,
     863                                       expected,
     864                                       debug_info)
     865  
     866          # test overflow
     867          ns = self.OVERFLOW_SECONDS * SEC_TO_NS
     868          ns_timestamps = (-ns, ns)
     869          overflow_values = convert_values(ns_timestamps)
     870          for time_rnd, _ in ROUNDING_MODES :
     871              for value in overflow_values:
     872                  debug_info = {'value': value, 'rounding': time_rnd}
     873                  with self.assertRaises(OverflowError, msg=debug_info):
     874                      pytime_converter(value, time_rnd)
     875  
     876      def check_int_rounding(self, pytime_converter, expected_func,
     877                             unit_to_sec=1, value_filter=None):
     878          self._check_rounding(pytime_converter, expected_func,
     879                               False, unit_to_sec, value_filter)
     880  
     881      def check_float_rounding(self, pytime_converter, expected_func,
     882                               unit_to_sec=1, value_filter=None):
     883          self._check_rounding(pytime_converter, expected_func,
     884                               True, unit_to_sec, value_filter)
     885  
     886      def decimal_round(self, x):
     887          d = decimal.Decimal(x)
     888          d = d.quantize(1)
     889          return int(d)
     890  
     891  
     892  class ESC[4;38;5;81mTestCPyTime(ESC[4;38;5;149mCPyTimeTestCase, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     893      """
     894      Test the C _PyTime_t API.
     895      """
     896      # _PyTime_t is a 64-bit signed integer
     897      OVERFLOW_SECONDS = math.ceil((2**63 + 1) / SEC_TO_NS)
     898  
     899      def test_FromSeconds(self):
     900          from _testcapi import PyTime_FromSeconds
     901  
     902          # PyTime_FromSeconds() expects a C int, reject values out of range
     903          def c_int_filter(secs):
     904              return (_testcapi.INT_MIN <= secs <= _testcapi.INT_MAX)
     905  
     906          self.check_int_rounding(lambda secs, rnd: PyTime_FromSeconds(secs),
     907                                  lambda secs: secs * SEC_TO_NS,
     908                                  value_filter=c_int_filter)
     909  
     910          # test nan
     911          for time_rnd, _ in ROUNDING_MODES:
     912              with self.assertRaises(TypeError):
     913                  PyTime_FromSeconds(float('nan'))
     914  
     915      def test_FromSecondsObject(self):
     916          from _testcapi import PyTime_FromSecondsObject
     917  
     918          self.check_int_rounding(
     919              PyTime_FromSecondsObject,
     920              lambda secs: secs * SEC_TO_NS)
     921  
     922          self.check_float_rounding(
     923              PyTime_FromSecondsObject,
     924              lambda ns: self.decimal_round(ns * SEC_TO_NS))
     925  
     926          # test nan
     927          for time_rnd, _ in ROUNDING_MODES:
     928              with self.assertRaises(ValueError):
     929                  PyTime_FromSecondsObject(float('nan'), time_rnd)
     930  
     931      def test_AsSecondsDouble(self):
     932          from _testcapi import PyTime_AsSecondsDouble
     933  
     934          def float_converter(ns):
     935              if abs(ns) % SEC_TO_NS == 0:
     936                  return float(ns // SEC_TO_NS)
     937              else:
     938                  return float(ns) / SEC_TO_NS
     939  
     940          self.check_int_rounding(lambda ns, rnd: PyTime_AsSecondsDouble(ns),
     941                                  float_converter,
     942                                  NS_TO_SEC)
     943  
     944          # test nan
     945          for time_rnd, _ in ROUNDING_MODES:
     946              with self.assertRaises(TypeError):
     947                  PyTime_AsSecondsDouble(float('nan'))
     948  
     949      def create_decimal_converter(self, denominator):
     950          denom = decimal.Decimal(denominator)
     951  
     952          def converter(value):
     953              d = decimal.Decimal(value) / denom
     954              return self.decimal_round(d)
     955  
     956          return converter
     957  
     958      def test_AsTimeval(self):
     959          from _testcapi import PyTime_AsTimeval
     960  
     961          us_converter = self.create_decimal_converter(US_TO_NS)
     962  
     963          def timeval_converter(ns):
     964              us = us_converter(ns)
     965              return divmod(us, SEC_TO_US)
     966  
     967          if sys.platform == 'win32':
     968              from _testcapi import LONG_MIN, LONG_MAX
     969  
     970              # On Windows, timeval.tv_sec type is a C long
     971              def seconds_filter(secs):
     972                  return LONG_MIN <= secs <= LONG_MAX
     973          else:
     974              seconds_filter = self.time_t_filter
     975  
     976          self.check_int_rounding(PyTime_AsTimeval,
     977                                  timeval_converter,
     978                                  NS_TO_SEC,
     979                                  value_filter=seconds_filter)
     980  
     981      @unittest.skipUnless(hasattr(_testcapi, 'PyTime_AsTimespec'),
     982                           'need _testcapi.PyTime_AsTimespec')
     983      def test_AsTimespec(self):
     984          from _testcapi import PyTime_AsTimespec
     985  
     986          def timespec_converter(ns):
     987              return divmod(ns, SEC_TO_NS)
     988  
     989          self.check_int_rounding(lambda ns, rnd: PyTime_AsTimespec(ns),
     990                                  timespec_converter,
     991                                  NS_TO_SEC,
     992                                  value_filter=self.time_t_filter)
     993  
     994      @unittest.skipUnless(hasattr(_testcapi, 'PyTime_AsTimeval_clamp'),
     995                           'need _testcapi.PyTime_AsTimeval_clamp')
     996      def test_AsTimeval_clamp(self):
     997          from _testcapi import PyTime_AsTimeval_clamp
     998  
     999          if sys.platform == 'win32':
    1000              from _testcapi import LONG_MIN, LONG_MAX
    1001              tv_sec_max = LONG_MAX
    1002              tv_sec_min = LONG_MIN
    1003          else:
    1004              tv_sec_max = self.time_t_max
    1005              tv_sec_min = self.time_t_min
    1006  
    1007          for t in (_PyTime_MIN, _PyTime_MAX):
    1008              ts = PyTime_AsTimeval_clamp(t, _PyTime.ROUND_CEILING)
    1009              with decimal.localcontext() as context:
    1010                  context.rounding = decimal.ROUND_CEILING
    1011                  us = self.decimal_round(decimal.Decimal(t) / US_TO_NS)
    1012              tv_sec, tv_usec = divmod(us, SEC_TO_US)
    1013              if tv_sec_max < tv_sec:
    1014                  tv_sec = tv_sec_max
    1015                  tv_usec = 0
    1016              elif tv_sec < tv_sec_min:
    1017                  tv_sec = tv_sec_min
    1018                  tv_usec = 0
    1019              self.assertEqual(ts, (tv_sec, tv_usec))
    1020  
    1021      @unittest.skipUnless(hasattr(_testcapi, 'PyTime_AsTimespec_clamp'),
    1022                           'need _testcapi.PyTime_AsTimespec_clamp')
    1023      def test_AsTimespec_clamp(self):
    1024          from _testcapi import PyTime_AsTimespec_clamp
    1025  
    1026          for t in (_PyTime_MIN, _PyTime_MAX):
    1027              ts = PyTime_AsTimespec_clamp(t)
    1028              tv_sec, tv_nsec = divmod(t, NS_TO_SEC)
    1029              if self.time_t_max < tv_sec:
    1030                  tv_sec = self.time_t_max
    1031                  tv_nsec = 0
    1032              elif tv_sec < self.time_t_min:
    1033                  tv_sec = self.time_t_min
    1034                  tv_nsec = 0
    1035              self.assertEqual(ts, (tv_sec, tv_nsec))
    1036  
    1037      def test_AsMilliseconds(self):
    1038          from _testcapi import PyTime_AsMilliseconds
    1039  
    1040          self.check_int_rounding(PyTime_AsMilliseconds,
    1041                                  self.create_decimal_converter(MS_TO_NS),
    1042                                  NS_TO_SEC)
    1043  
    1044      def test_AsMicroseconds(self):
    1045          from _testcapi import PyTime_AsMicroseconds
    1046  
    1047          self.check_int_rounding(PyTime_AsMicroseconds,
    1048                                  self.create_decimal_converter(US_TO_NS),
    1049                                  NS_TO_SEC)
    1050  
    1051  
    1052  class ESC[4;38;5;81mTestOldPyTime(ESC[4;38;5;149mCPyTimeTestCase, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1053      """
    1054      Test the old C _PyTime_t API: _PyTime_ObjectToXXX() functions.
    1055      """
    1056  
    1057      # time_t is a 32-bit or 64-bit signed integer
    1058      OVERFLOW_SECONDS = 2 ** 64
    1059  
    1060      def test_object_to_time_t(self):
    1061          from _testcapi import pytime_object_to_time_t
    1062  
    1063          self.check_int_rounding(pytime_object_to_time_t,
    1064                                  lambda secs: secs,
    1065                                  value_filter=self.time_t_filter)
    1066  
    1067          self.check_float_rounding(pytime_object_to_time_t,
    1068                                    self.decimal_round,
    1069                                    value_filter=self.time_t_filter)
    1070  
    1071      def create_converter(self, sec_to_unit):
    1072          def converter(secs):
    1073              floatpart, intpart = math.modf(secs)
    1074              intpart = int(intpart)
    1075              floatpart *= sec_to_unit
    1076              floatpart = self.decimal_round(floatpart)
    1077              if floatpart < 0:
    1078                  floatpart += sec_to_unit
    1079                  intpart -= 1
    1080              elif floatpart >= sec_to_unit:
    1081                  floatpart -= sec_to_unit
    1082                  intpart += 1
    1083              return (intpart, floatpart)
    1084          return converter
    1085  
    1086      def test_object_to_timeval(self):
    1087          from _testcapi import pytime_object_to_timeval
    1088  
    1089          self.check_int_rounding(pytime_object_to_timeval,
    1090                                  lambda secs: (secs, 0),
    1091                                  value_filter=self.time_t_filter)
    1092  
    1093          self.check_float_rounding(pytime_object_to_timeval,
    1094                                    self.create_converter(SEC_TO_US),
    1095                                    value_filter=self.time_t_filter)
    1096  
    1097           # test nan
    1098          for time_rnd, _ in ROUNDING_MODES:
    1099              with self.assertRaises(ValueError):
    1100                  pytime_object_to_timeval(float('nan'), time_rnd)
    1101  
    1102      def test_object_to_timespec(self):
    1103          from _testcapi import pytime_object_to_timespec
    1104  
    1105          self.check_int_rounding(pytime_object_to_timespec,
    1106                                  lambda secs: (secs, 0),
    1107                                  value_filter=self.time_t_filter)
    1108  
    1109          self.check_float_rounding(pytime_object_to_timespec,
    1110                                    self.create_converter(SEC_TO_NS),
    1111                                    value_filter=self.time_t_filter)
    1112  
    1113          # test nan
    1114          for time_rnd, _ in ROUNDING_MODES:
    1115              with self.assertRaises(ValueError):
    1116                  pytime_object_to_timespec(float('nan'), time_rnd)
    1117  
    1118  @unittest.skipUnless(sys.platform == "darwin", "test weak linking on macOS")
    1119  class ESC[4;38;5;81mTestTimeWeaklinking(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1120      # These test cases verify that weak linking support on macOS works
    1121      # as expected. These cases only test new behaviour introduced by weak linking,
    1122      # regular behaviour is tested by the normal test cases.
    1123      #
    1124      # See the section on Weak Linking in Mac/README.txt for more information.
    1125      def test_clock_functions(self):
    1126          import sysconfig
    1127          import platform
    1128  
    1129          config_vars = sysconfig.get_config_vars()
    1130          var_name = "HAVE_CLOCK_GETTIME"
    1131          if var_name not in config_vars or not config_vars[var_name]:
    1132              raise unittest.SkipTest(f"{var_name} is not available")
    1133  
    1134          mac_ver = tuple(int(x) for x in platform.mac_ver()[0].split("."))
    1135  
    1136          clock_names = [
    1137              "CLOCK_MONOTONIC", "clock_gettime", "clock_gettime_ns", "clock_settime",
    1138              "clock_settime_ns", "clock_getres"]
    1139  
    1140          if mac_ver >= (10, 12):
    1141              for name in clock_names:
    1142                  self.assertTrue(hasattr(time, name), f"time.{name} is not available")
    1143  
    1144          else:
    1145              for name in clock_names:
    1146                  self.assertFalse(hasattr(time, name), f"time.{name} is available")
    1147  
    1148  
    1149  if __name__ == "__main__":
    1150      unittest.main()