ยปCore Development>Code coverage>Lib/test/test_time.py

Python code coverage for Lib/test/test_time.py

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