GH-103944: Remove last use of `utcfromtimestamp` (#103995)

* Remove last use of `utcfromtimestamp`

This was a weirdly valid use of `utcfromtimestamp` in the sense that the "timestamps" in TZif files are not epoch times, but actually something more properly thought of as "number of seconds since 1970 in the local time zone", so even though we didn't want UTC time, `utcfromtimestamp` was still a good way to get the thing we wanted. Since we're deprecating `utcfromtimestamp`, it's just as valid to use `timedelta` arithmetic here.

We may be able to avoid the question entirely by switching these tests over to using `ZoneInfo` in the future.

* Fix a few missing DeprecationWarnings in tests

In one test, we simply turn off DeprecationWarning rather than asserting about it, because whether the error condition happens before or after the warning seems to differ between the Python and C versions.
This commit is contained in:
Paul Ganssle 2023-05-03 11:17:27 -04:00 committed by GitHub
parent 0fc58c66ba
commit 38dc3f28dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 15 deletions

View File

@ -2,18 +2,19 @@
See https://www.zope.dev/Members/fdrake/DateTimeWiki/TestCases
"""
import io
import itertools
import bisect
import copy
import decimal
import sys
import io
import itertools
import os
import pickle
import random
import re
import struct
import sys
import unittest
import warnings
from array import array
@ -51,11 +52,12 @@ pickle_choices = [(pickle, pickle, proto)
for proto in range(pickle.HIGHEST_PROTOCOL + 1)]
assert len(pickle_choices) == pickle.HIGHEST_PROTOCOL + 1
EPOCH_NAIVE = datetime(1970, 1, 1, 0, 0) # For calculating transitions
# An arbitrary collection of objects of non-datetime types, for testing
# mixed-type comparisons.
OTHERSTUFF = (10, 34.5, "abc", {}, [], ())
# XXX Copied from test_float.
INF = float("inf")
NAN = float("nan")
@ -2626,9 +2628,10 @@ class TestDateTime(TestDate):
for test_name, ts in test_cases:
with self.subTest(test_name, ts=ts):
with self.assertRaises((ValueError, OverflowError)):
# converting a Python int to C time_t can raise a
# OverflowError, especially on 32-bit platforms.
self.theclass.utcfromtimestamp(ts)
with self.assertWarns(DeprecationWarning):
# converting a Python int to C time_t can raise a
# OverflowError, especially on 32-bit platforms.
self.theclass.utcfromtimestamp(ts)
def test_insane_fromtimestamp(self):
# It's possible that some platform maps time_t to double,
@ -2645,8 +2648,9 @@ class TestDateTime(TestDate):
# exempt such platforms (provided they return reasonable
# results!).
for insane in -1e200, 1e200:
self.assertRaises(OverflowError, self.theclass.utcfromtimestamp,
insane)
with self.assertWarns(DeprecationWarning):
self.assertRaises(OverflowError, self.theclass.utcfromtimestamp,
insane)
@unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps")
def test_negative_float_fromtimestamp(self):
@ -3005,7 +3009,7 @@ class TestDateTime(TestDate):
for name, meth_name, kwargs in test_cases:
with self.subTest(name):
constr = getattr(DateTimeSubclass, meth_name)
if constr == "utcnow":
if meth_name == "utcnow":
with self.assertWarns(DeprecationWarning):
dt = constr(**kwargs)
else:
@ -4733,8 +4737,10 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase):
# Try with and without naming the keyword; for whatever reason,
# utcfromtimestamp() doesn't accept a tzinfo argument.
off42 = FixedOffset(42, "42")
self.assertRaises(TypeError, meth, ts, off42)
self.assertRaises(TypeError, meth, ts, tzinfo=off42)
with warnings.catch_warnings(category=DeprecationWarning):
warnings.simplefilter("ignore", category=DeprecationWarning)
self.assertRaises(TypeError, meth, ts, off42)
self.assertRaises(TypeError, meth, ts, tzinfo=off42)
def test_tzinfo_timetuple(self):
# TestDateTime tested most of this. datetime adds a twist to the
@ -6102,15 +6108,14 @@ class ZoneInfo(tzinfo):
def transitions(self):
for (_, prev_ti), (t, ti) in pairs(zip(self.ut, self.ti)):
shift = ti[0] - prev_ti[0]
# TODO: Remove this use of utcfromtimestamp
yield datetime.utcfromtimestamp(t), shift
yield (EPOCH_NAIVE + timedelta(seconds=t)), shift
def nondst_folds(self):
"""Find all folds with the same value of isdst on both sides of the transition."""
for (_, prev_ti), (t, ti) in pairs(zip(self.ut, self.ti)):
shift = ti[0] - prev_ti[0]
if shift < ZERO and ti[1] == prev_ti[1]:
yield datetime.utcfromtimestamp(t), -shift, prev_ti[2], ti[2]
yield _utcfromtimestamp(datetime, t,), -shift, prev_ti[2], ti[2]
@classmethod
def print_all_nondst_folds(cls, same_abbr=False, start_year=1):