-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathstdlib_time.py
More file actions
124 lines (104 loc) · 3.99 KB
/
Copy pathstdlib_time.py
File metadata and controls
124 lines (104 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import sys
import time
x = time.gmtime(1000)
assert x.tm_year == 1970
assert x.tm_min == 16
assert x.tm_sec == 40
assert x.tm_isdst == 0
s = time.strftime("%Y-%m-%d-%H-%M-%S", x)
# print(s)
assert s == "1970-01-01-00-16-40"
if sys.platform != "wasi":
# _strptime depends on time.tzname, which is not available on WASI yet.
x2 = time.strptime(s, "%Y-%m-%d-%H-%M-%S")
assert x2.tm_min == 16
# TODO: WASI currently does not raise OverflowError for some out-of-range
# struct_time values in asctime() and strftime().
# Re-enable this regression on WASI once the non-Unix time conversion path is fixed.
# Regression test for RustPython issue #4938:
# struct_time field overflow should raise OverflowError (matching CPython),
# not TypeError. Covers mktime, asctime, and strftime.
I32_MAX_PLUS_1 = 2147483648
overflow_cases = [
(I32_MAX_PLUS_1, 1, 1, 0, 0, 0, 0, 0, 0), # i32 overflow in year
(2024, I32_MAX_PLUS_1, 1, 0, 0, 0, 0, 0, 0), # i32 overflow in month
(2024, 1, I32_MAX_PLUS_1, 0, 0, 0, 0, 0, 0), # i32 overflow in mday
(2024, 1, 1, 0, 0, I32_MAX_PLUS_1, 0, 0, 0), # i32 overflow in sec
(88888888888,) * 9, # multi-field i32 overflow
]
for case in overflow_cases:
for func_name, call in [
("mktime", lambda c=case: time.mktime(c)),
("asctime", lambda c=case: time.asctime(c)),
("strftime", lambda c=case: time.strftime("%Y", c)),
]:
try:
call()
except OverflowError:
pass # expected, matches CPython
except TypeError as e:
raise AssertionError(
f"{func_name}({case}) raised TypeError (should be OverflowError): {e}"
) from e
else:
raise AssertionError(
f"{func_name}({case}) did not raise — expected OverflowError"
)
s = time.asctime(x)
assert s == "Thu Jan 1 00:16:40 1970"
# Monotonic and performance clocks should advance with elapsed time.
monotonic_before = time.monotonic()
monotonic_ns = time.monotonic_ns()
monotonic_after = time.monotonic()
assert isinstance(monotonic_before, float)
assert isinstance(monotonic_ns, int)
assert monotonic_before <= monotonic_ns / 1_000_000_000 <= monotonic_after
perf_before = time.perf_counter()
perf_ns = time.perf_counter_ns()
perf_after = time.perf_counter()
assert isinstance(perf_before, float)
assert isinstance(perf_ns, int)
assert perf_before <= perf_ns / 1_000_000_000 <= perf_after
monotonic_start = time.monotonic()
perf_start = time.perf_counter()
time.sleep(0.02)
monotonic_elapsed = time.monotonic() - monotonic_start
perf_elapsed = time.perf_counter() - perf_start
assert monotonic_elapsed >= 0.01
assert perf_elapsed >= 0.01
# The optional second argument fills the fields that are not part of the
# sequence.
fields = (2024, 1, 2, 3, 4, 5, 6, 7, 0)
assert time.struct_time(fields).tm_zone is None
assert time.struct_time(fields, {"tm_zone": "UTC"}).tm_zone == "UTC"
assert time.struct_time(fields, {"tm_gmtoff": 60}).tm_gmtoff == 60
try:
time.struct_time(fields, ["tm_zone", "UTC"])
except TypeError:
pass
else:
assert False, "struct_time accepted a non-dict second argument"
if hasattr(time, "tzset"):
import os
old_tz = os.environ.get("TZ")
try:
os.environ["TZ"] = "EST+05EDT,M3.2.0,M11.1.0"
time.tzset()
assert time.timezone == 18000
assert time.altzone == 14400
if hasattr(time, "daylight"):
assert time.daylight == 1
assert time.tzname == ("EST", "EDT")
assert len(time.tzname) == 2
os.environ["TZ"] = "UTC+0"
time.tzset()
assert time.timezone == 0
if hasattr(time, "daylight"):
assert time.daylight == 0
assert time.tzname == ("UTC", "UTC")
finally:
if old_tz is not None:
os.environ["TZ"] = old_tz
elif "TZ" in os.environ:
del os.environ["TZ"]
time.tzset()