Replace tz.UTC with dateutil.tz.tzutc()

As discussed in https://review.opendev.org/#/c/742477/, this patch
replaces the use of `tz.UTC` with `dateutil.tz.tzutc()`

Also add python-dateutil to requirements.txt, using the same minimum
version as several other OpenStack projects, including nova.

Change-Id: I4da9e8854a571058e48c2f51c1d340bc135cfe2b
This commit is contained in:
Rafael Weingärtner 2020-08-19 20:03:51 -03:00 committed by Pierre Riteau
parent 8877fa1a37
commit b7abb9bb69
11 changed files with 49 additions and 40 deletions

View File

@ -157,8 +157,8 @@ class GnocchiCollectorAggregationOperationTest(tests.TestCase):
def setUp(self): def setUp(self):
super(GnocchiCollectorAggregationOperationTest, self).setUp() super(GnocchiCollectorAggregationOperationTest, self).setUp()
self.conf.set_override('collector', 'gnocchi', 'collect') self.conf.set_override('collector', 'gnocchi', 'collect')
self.start = datetime.datetime(2019, 1, 1, tzinfo=tz.UTC) self.start = datetime.datetime(2019, 1, 1, tzinfo=tz.tzutc())
self.end = datetime.datetime(2019, 1, 1, 1, tzinfo=tz.UTC) self.end = datetime.datetime(2019, 1, 1, 1, tzinfo=tz.tzutc())
def do_test(self, expected_op, extra_args=None): def do_test(self, expected_op, extra_args=None):
conf = { conf = {

View File

@ -54,7 +54,7 @@ from cloudkitty import utils as ck_utils
from cloudkitty.utils import tz as tzutils from cloudkitty.utils import tz as tzutils
INITIAL_DT = datetime.datetime(2015, 1, 1, tzinfo=tz.UTC) INITIAL_DT = datetime.datetime(2015, 1, 1, tzinfo=tz.tzutc())
class UUIDFixture(fixture.GabbiFixture): class UUIDFixture(fixture.GabbiFixture):
@ -377,7 +377,7 @@ class StorageDataFixture(BaseStorageDataFixture):
class NowStorageDataFixture(BaseStorageDataFixture): class NowStorageDataFixture(BaseStorageDataFixture):
def initialize_data(self): def initialize_data(self):
dt = tzutils.get_month_start(naive=True).replace(tzinfo=tz.UTC) dt = tzutils.get_month_start(naive=True).replace(tzinfo=tz.tzutc())
hour_delta = datetime.timedelta(seconds=3600) hour_delta = datetime.timedelta(seconds=3600)
limit = dt + hour_delta * 12 limit = dt + hour_delta * 12
while dt < limit: while dt < limit:
@ -501,7 +501,7 @@ class InfluxStorageDataFixture(StorageDataFixture):
class UTCFixture(fixture.GabbiFixture): class UTCFixture(fixture.GabbiFixture):
"""Set the local timezone to UTC""" """Set the local timezone to UTC"""
def start_fixture(self): def start_fixture(self):
self._tzmock = mock.patch('cloudkitty.utils.tz._LOCAL_TZ', tz.UTC) self._tzmock = mock.patch('cloudkitty.utils.tz._LOCAL_TZ', tz.tzutc())
self._tzmock.start() self._tzmock.start()
def stop_fixture(self): def stop_fixture(self):

View File

@ -38,8 +38,8 @@ class TestElasticsearchClient(unittest.TestCase):
self.assertEqual(self.client._build_must(None, None, None, None), []) self.assertEqual(self.client._build_must(None, None, None, None), [])
def test_build_must_with_start_end(self): def test_build_must_with_start_end(self):
start = datetime.datetime(2019, 8, 30, tzinfo=tz.UTC) start = datetime.datetime(2019, 8, 30, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 8, 31, tzinfo=tz.UTC) end = datetime.datetime(2019, 8, 31, tzinfo=tz.tzutc())
self.assertEqual( self.assertEqual(
self.client._build_must(start, end, None, None), self.client._build_must(start, end, None, None),
[{'range': {'start': {'gte': '2019-08-30T00:00:00+00:00'}}}, [{'range': {'start': {'gte': '2019-08-30T00:00:00+00:00'}}},

View File

@ -42,7 +42,7 @@ class TestInfluxDBStorage(TestCase):
'two': '2', 'two': '2',
'1': 'one', '1': 'one',
'2': 'two', '2': 'two',
'time': datetime(2019, 1, 1, tzinfo=tz.UTC).isoformat(), 'time': datetime(2019, 1, 1, tzinfo=tz.tzutc()).isoformat(),
} }
def test_point_to_dataframe_entry_valid_point(self): def test_point_to_dataframe_entry_valid_point(self):
@ -81,10 +81,11 @@ class TestInfluxDBStorage(TestCase):
self.assertEqual(len(dataframes), 3) self.assertEqual(len(dataframes), 3)
for idx, frame in enumerate(dataframes): for idx, frame in enumerate(dataframes):
self.assertEqual(frame.start, datetime(2019, 1, 1, tzinfo=tz.UTC)) self.assertEqual(
frame.start, datetime(2019, 1, 1, tzinfo=tz.tzutc()))
delta = timedelta(seconds=(idx + 1) * 100) delta = timedelta(seconds=(idx + 1) * 100)
self.assertEqual(frame.end, self.assertEqual(frame.end,
datetime(2019, 1, 1, tzinfo=tz.UTC) + delta) datetime(2019, 1, 1, tzinfo=tz.tzutc()) + delta)
typelist = list(frame.itertypes()) typelist = list(frame.itertypes())
self.assertEqual(len(typelist), 1) self.assertEqual(len(typelist), 1)
type_, points = typelist[0] type_, points = typelist[0]

View File

@ -154,8 +154,8 @@ class TestDataPoint(unittest.TestCase):
class TestDataFrame(unittest.TestCase): class TestDataFrame(unittest.TestCase):
def test_dataframe_add_points(self): def test_dataframe_add_points(self):
start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.UTC) start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.UTC) end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.tzutc())
df = dataframe.DataFrame(start=start, end=end) df = dataframe.DataFrame(start=start, end=end)
a_points = [dataframe.DataPoint(**TestDataPoint.default_params) a_points = [dataframe.DataPoint(**TestDataPoint.default_params)
for _ in range(2)] for _ in range(2)]
@ -183,15 +183,15 @@ class TestDataFrame(unittest.TestCase):
}) })
def test_properties(self): def test_properties(self):
start = datetime.datetime(2019, 6, 1, tzinfo=tz.UTC) start = datetime.datetime(2019, 6, 1, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 6, 1, 1, tzinfo=tz.UTC) end = datetime.datetime(2019, 6, 1, 1, tzinfo=tz.tzutc())
df = dataframe.DataFrame(start=start, end=end) df = dataframe.DataFrame(start=start, end=end)
self.assertEqual(df.start, start) self.assertEqual(df.start, start)
self.assertEqual(df.end, end) self.assertEqual(df.end, end)
def test_json(self): def test_json(self):
start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.UTC) start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.UTC) end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.tzutc())
df = dataframe.DataFrame(start=start, end=end) df = dataframe.DataFrame(start=start, end=end)
a_points = [dataframe.DataPoint(**TestDataPoint.default_params) a_points = [dataframe.DataPoint(**TestDataPoint.default_params)
for _ in range(2)] for _ in range(2)]
@ -217,8 +217,8 @@ class TestDataFrame(unittest.TestCase):
}))) })))
def test_from_dict_valid_dict(self): def test_from_dict_valid_dict(self):
start = datetime.datetime(2019, 1, 2, 12, tzinfo=tz.UTC) start = datetime.datetime(2019, 1, 2, 12, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 1, 2, 13, tzinfo=tz.UTC) end = datetime.datetime(2019, 1, 2, 13, tzinfo=tz.tzutc())
point = dataframe.DataPoint( point = dataframe.DataPoint(
'unit', 0, 0, {'g_one': 'one'}, {'m_two': 'two'}) 'unit', 0, 0, {'g_one': 'one'}, {'m_two': 'two'})
usage = {'metric_x': [point]} usage = {'metric_x': [point]}
@ -232,8 +232,8 @@ class TestDataFrame(unittest.TestCase):
) )
def test_from_dict_valid_dict_date_as_str(self): def test_from_dict_valid_dict_date_as_str(self):
start = datetime.datetime(2019, 1, 2, 12, tzinfo=tz.UTC) start = datetime.datetime(2019, 1, 2, 12, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 1, 2, 13, tzinfo=tz.UTC) end = datetime.datetime(2019, 1, 2, 13, tzinfo=tz.tzutc())
point = dataframe.DataPoint( point = dataframe.DataPoint(
'unit', 0, 0, {'g_one': 'one'}, {'m_two': 'two'}) 'unit', 0, 0, {'g_one': 'one'}, {'m_two': 'two'})
usage = {'metric_x': [point]} usage = {'metric_x': [point]}
@ -251,8 +251,8 @@ class TestDataFrame(unittest.TestCase):
ValueError, dataframe.DataFrame.from_dict, {'usage': None}) ValueError, dataframe.DataFrame.from_dict, {'usage': None})
def test_repr(self): def test_repr(self):
start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.UTC) start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.UTC) end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.tzutc())
df = dataframe.DataFrame(start=start, end=end) df = dataframe.DataFrame(start=start, end=end)
points = [dataframe.DataPoint(**TestDataPoint.default_params) points = [dataframe.DataPoint(**TestDataPoint.default_params)
for _ in range(4)] for _ in range(4)]
@ -262,8 +262,8 @@ class TestDataFrame(unittest.TestCase):
self.assertEqual(str(df), "DataFrame(metrics=[metric_x,metric_y])") self.assertEqual(str(df), "DataFrame(metrics=[metric_x,metric_y])")
def test_iterpoints(self): def test_iterpoints(self):
start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.UTC) start = datetime.datetime(2019, 3, 4, 1, tzinfo=tz.tzutc())
end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.UTC) end = datetime.datetime(2019, 3, 4, 2, tzinfo=tz.tzutc())
df = dataframe.DataFrame(start=start, end=end) df = dataframe.DataFrame(start=start, end=end)
points = [dataframe.DataPoint(**TestDataPoint.default_params) points = [dataframe.DataPoint(**TestDataPoint.default_params)
for _ in range(4)] for _ in range(4)]

View File

@ -28,6 +28,6 @@ class JSONEncoderTest(tests.TestCase):
self.assertEqual(json.dumps(obj), '{"nb": 42.0}') self.assertEqual(json.dumps(obj), '{"nb": 42.0}')
def test_encode_datetime(self): def test_encode_datetime(self):
obj = {'date': datetime.datetime(2019, 1, 1, tzinfo=tz.UTC)} obj = {'date': datetime.datetime(2019, 1, 1, tzinfo=tz.tzutc())}
self.assertEqual(json.dumps(obj), self.assertEqual(json.dumps(obj),
'{"date": "2019-01-01T00:00:00+00:00"}') '{"date": "2019-01-01T00:00:00+00:00"}')

View File

@ -31,7 +31,7 @@ class TestTZUtils(unittest.TestCase):
def test_localized_now(self): def test_localized_now(self):
self.assertEqual( self.assertEqual(
self.local_now.astimezone(tz.UTC).replace(tzinfo=None), self.local_now.astimezone(tz.tzutc()).replace(tzinfo=None),
self.naive_now) self.naive_now)
self.assertIsNotNone(self.local_now.tzinfo) self.assertIsNotNone(self.local_now.tzinfo)
@ -63,15 +63,15 @@ class TestTZUtils(unittest.TestCase):
def _test_add_substract_delta(self, obj, tzone): def _test_add_substract_delta(self, obj, tzone):
delta = datetime.timedelta(seconds=3600) delta = datetime.timedelta(seconds=3600)
naive = obj.astimezone(tz.UTC).replace(tzinfo=None) naive = obj.astimezone(tz.tzutc()).replace(tzinfo=None)
self.assertEqual( self.assertEqual(
tzutils.add_delta(obj, delta).astimezone(tzone), tzutils.add_delta(obj, delta).astimezone(tzone),
(naive + delta).replace(tzinfo=tz.UTC).astimezone(tzone), (naive + delta).replace(tzinfo=tz.tzutc()).astimezone(tzone),
) )
self.assertEqual( self.assertEqual(
tzutils.substract_delta(obj, delta).astimezone(tzone), tzutils.substract_delta(obj, delta).astimezone(tzone),
(naive - delta).replace(tzinfo=tz.UTC).astimezone(tzone), (naive - delta).replace(tzinfo=tz.tzutc()).astimezone(tzone),
) )
def test_add_substract_delta_summertime(self): def test_add_substract_delta_summertime(self):
@ -118,13 +118,13 @@ class TestTZUtils(unittest.TestCase):
self.assertEqual(tzutils.diff_seconds(two, one), 30) self.assertEqual(tzutils.diff_seconds(two, one), 30)
def test_diff_seconds_positive_arg_aware_objects(self): def test_diff_seconds_positive_arg_aware_objects(self):
one = datetime.datetime(2019, 1, 1, 1, 1, 30, tzinfo=tz.UTC) one = datetime.datetime(2019, 1, 1, 1, 1, 30, tzinfo=tz.tzutc())
two = datetime.datetime(2019, 1, 1, 1, 1, tzinfo=tz.UTC) two = datetime.datetime(2019, 1, 1, 1, 1, tzinfo=tz.tzutc())
self.assertEqual(tzutils.diff_seconds(one, two), 30) self.assertEqual(tzutils.diff_seconds(one, two), 30)
def test_diff_seconds_negative_arg_aware_objects(self): def test_diff_seconds_negative_arg_aware_objects(self):
one = datetime.datetime(2019, 1, 1, 1, 1, 30, tzinfo=tz.UTC) one = datetime.datetime(2019, 1, 1, 1, 1, 30, tzinfo=tz.tzutc())
two = datetime.datetime(2019, 1, 1, 1, 1, tzinfo=tz.UTC) two = datetime.datetime(2019, 1, 1, 1, 1, tzinfo=tz.tzutc())
self.assertEqual(tzutils.diff_seconds(two, one), 30) self.assertEqual(tzutils.diff_seconds(two, one), 30)
def test_diff_seconds_negative_arg_aware_objects_on_summer_change(self): def test_diff_seconds_negative_arg_aware_objects_on_summer_change(self):
@ -136,7 +136,7 @@ class TestTZUtils(unittest.TestCase):
def test_cloudkitty_dt_from_ts_as_utc(self): def test_cloudkitty_dt_from_ts_as_utc(self):
ts = 1569902400 ts = 1569902400
dt = datetime.datetime(2019, 10, 1, 4, tzinfo=tz.UTC) dt = datetime.datetime(2019, 10, 1, 4, tzinfo=tz.tzutc())
self.assertEqual(dt, tzutils.dt_from_ts(ts, as_utc=True)) self.assertEqual(dt, tzutils.dt_from_ts(ts, as_utc=True))
def test_cloudkitty_dt_from_ts_local_tz(self): def test_cloudkitty_dt_from_ts_local_tz(self):

View File

@ -47,9 +47,9 @@ def local_to_utc(dt, naive=False):
# applied to a naive datetime object. In python3 however, the naive object # applied to a naive datetime object. In python3 however, the naive object
# is considered as being in the system's time. # is considered as being in the system's time.
if dt.tzinfo is None: if dt.tzinfo is None:
dt = dt.replace(tzinfo=tz.UTC) dt = dt.replace(tzinfo=tz.tzutc())
output = dt.astimezone(tz.UTC) output = dt.astimezone(tz.tzutc())
if naive: if naive:
output = output.replace(tzinfo=None) output = output.replace(tzinfo=None)
return output return output
@ -65,7 +65,7 @@ def utc_to_local(dt):
:rtype: datetime.datetime :rtype: datetime.datetime
""" """
if dt.tzinfo is None: if dt.tzinfo is None:
dt = dt.replace(tzinfo=tz.UTC) dt = dt.replace(tzinfo=tz.tzutc())
return dt.astimezone(_LOCAL_TZ) return dt.astimezone(_LOCAL_TZ)
@ -81,7 +81,7 @@ def dt_from_iso(time_str, as_utc=False):
:rtype: datetime.datetime :rtype: datetime.datetime
""" """
return timeutils.parse_isotime(time_str).astimezone( return timeutils.parse_isotime(time_str).astimezone(
tz.UTC if as_utc else _LOCAL_TZ).replace(microsecond=0) tz.tzutc() if as_utc else _LOCAL_TZ).replace(microsecond=0)
def dt_from_ts(ts, as_utc=False): def dt_from_ts(ts, as_utc=False):
@ -89,7 +89,8 @@ def dt_from_ts(ts, as_utc=False):
Returns the object as being from the local timezone. Returns the object as being from the local timezone.
""" """
return datetime.datetime.fromtimestamp(ts, tz.UTC if as_utc else _LOCAL_TZ) return datetime.datetime.fromtimestamp(
ts, tz.tzutc() if as_utc else _LOCAL_TZ)
def add_delta(dt, delta): def add_delta(dt, delta):
@ -134,7 +135,7 @@ def get_month_start(dt=None, naive=False):
if not dt: if not dt:
dt = localized_now() dt = localized_now()
if not dt.tzinfo: if not dt.tzinfo:
dt = dt.replace(tzinfo=tz.UTC).astimezone(_LOCAL_TZ) dt = dt.replace(tzinfo=tz.tzutc()).astimezone(_LOCAL_TZ)
if naive: if naive:
dt = local_to_utc(dt, naive=True) dt = local_to_utc(dt, naive=True)
return datetime.datetime(dt.year, dt.month, 1, tzinfo=dt.tzinfo) return datetime.datetime(dt.year, dt.month, 1, tzinfo=dt.tzinfo)

View File

@ -21,6 +21,7 @@ oslo.middleware==3.27.0 # Apache-2.0
oslo.policy==0.5.0 # Apache-2.0 oslo.policy==0.5.0 # Apache-2.0
oslo.utils==3.5.0 # Apache-2.0 oslo.utils==3.5.0 # Apache-2.0
oslo.upgradecheck==0.1.1 # Apache-2.0 oslo.upgradecheck==0.1.1 # Apache-2.0
python-dateutil==2.5.3 # BSD
SQLAlchemy==1.0.10 # MIT SQLAlchemy==1.0.10 # MIT
six==1.9.0 # MIT six==1.9.0 # MIT
stevedore==1.5.0 # Apache-2.0 stevedore==1.5.0 # Apache-2.0

View File

@ -0,0 +1,5 @@
---
fixes:
- |
The use of ``tz.UTC`` from the ``dateutil`` package was removed, bringing
compatibility with the version available in RHEL and CentOS 8.

View File

@ -23,6 +23,7 @@ oslo.middleware>=3.27.0 # Apache-2.0
oslo.policy>=0.5.0 # Apache-2.0 oslo.policy>=0.5.0 # Apache-2.0
oslo.utils>=3.5.0 # Apache-2.0 oslo.utils>=3.5.0 # Apache-2.0
oslo.upgradecheck>=0.1.1 # Apache-2.0 oslo.upgradecheck>=0.1.1 # Apache-2.0
python-dateutil>=2.5.3 # BSD
SQLAlchemy>=1.0.10,!=1.1.5,!=1.1.6,!=1.1.7,!=1.1.8 # MIT SQLAlchemy>=1.0.10,!=1.1.5,!=1.1.6,!=1.1.7,!=1.1.8 # MIT
six>=1.9.0 # MIT six>=1.9.0 # MIT
stevedore>=1.5.0 # Apache-2.0 stevedore>=1.5.0 # Apache-2.0