Implement zoneinfo support to drop dependency to pytz

Zoneinfo was introduced within python 3.9.

The support of pytz will be removed within RHEL 10 [1].

2023.2 (bobcat) will move our testing runtime to py3.9 and py3.10
so we want to see pytz removed within this series.

tzdata is required at runtime in our gates, because, by default,
zoneinfo uses the system’s time zone data if available; if no system
time zone data is available, the library will fall back to using the
first-party tzdata package available on PyPI. Apparently our gates have no
time zone data available nor tzdata installed by default because we get the
following error without tzdata installed [3]:
`ModuleNotFoundError: No module named 'tzdata'

So I prefer to add tzdata in our requirements to avoid runtime failure
related to time zone and ensure that time zone are always available.

[1] https://issues.redhat.com/browse/RHEL-219
[2] https://review.opendev.org/c/openstack/governance/+/872232
[3]
https://zuul.opendev.org/t/openstack/build/0a1576775e894b09bc31269fea00ba03/log/job-output.txt#1445`

Depends-on: https://review.opendev.org/c/openstack/requirements/+/875854
Change-Id: I8d87d54f6f5ded8caee6cb780bacb39afea0fea1
This commit is contained in:
Hervé Beraud 2023-02-07 14:42:48 +01:00
parent e3307fde6e
commit a326ec5eea
4 changed files with 21 additions and 13 deletions

View File

@ -33,10 +33,10 @@ import functools
import itertools
import uuid
from xmlrpc import client as xmlrpclib
import zoneinfo
import msgpack
from oslo_utils import importutils
from pytz import timezone
netaddr = importutils.try_import("netaddr")
@ -236,7 +236,7 @@ class DateTimeHandler(object):
'microsecond': dt.microsecond,
}
if dt.tzinfo:
tz = dt.tzinfo.tzname(None)
tz = str(dt.tzinfo)
dct['tz'] = tz
return dumps(dct, registry=self._registry)
@ -263,9 +263,9 @@ class DateTimeHandler(object):
minute=dct['minute'],
second=dct['second'],
microsecond=dct['microsecond'])
if 'tz' in dct:
tzinfo = timezone(dct['tz'])
dt = tzinfo.localize(dt)
if 'tz' in dct and dct['tz']:
tzinfo = zoneinfo.ZoneInfo(dct['tz'])
dt = dt.replace(tzinfo=tzinfo)
return dt

View File

@ -15,10 +15,10 @@
import datetime
import itertools
from xmlrpc import client as xmlrpclib
import zoneinfo
import netaddr
from oslotest import base as test_base
from pytz import timezone
from oslo_serialization import msgpackutils
from oslo_utils import uuidutils
@ -145,20 +145,22 @@ class MsgPackUtilsTest(test_base.BaseTestCase):
self.assertEqual(today, _dumps_loads(today))
def test_datetime_tz_clone(self):
eastern = timezone('US/Eastern')
eastern = zoneinfo.ZoneInfo('US/Eastern')
now = datetime.datetime.now()
e_dt = eastern.localize(now)
e_dt = now.replace(tzinfo=eastern)
e_dt2 = _dumps_loads(e_dt)
self.assertEqual(e_dt, e_dt2)
self.assertEqual(e_dt.strftime(_TZ_FMT), e_dt2.strftime(_TZ_FMT))
def test_datetime_tz_different(self):
eastern = timezone('US/Eastern')
pacific = timezone('US/Pacific')
eastern = zoneinfo.ZoneInfo('US/Eastern')
pacific = zoneinfo.ZoneInfo('US/Pacific')
now = datetime.datetime.now()
e_dt = eastern.localize(now)
p_dt = pacific.localize(now)
now = now.replace(tzinfo=eastern)
e_dt = now
now = now.replace(tzinfo=pacific)
p_dt = now
self.assertNotEqual(e_dt, p_dt)
self.assertNotEqual(e_dt.strftime(_TZ_FMT), p_dt.strftime(_TZ_FMT))

View File

@ -0,0 +1,6 @@
---
other:
- |
Implement zoneinfo to allow us to remove pytz's dependency. zoneinfo
was introduced by python 3.9, and the series 2023.2 (bobcat) set py39
as the minimal supported runtime, so we are able to remove pytz.

View File

@ -10,4 +10,4 @@
pbr!=2.1.0,>=2.0.0 # Apache-2.0
msgpack>=0.5.2 # Apache-2.0
oslo.utils>=3.33.0 # Apache-2.0
pytz>=2013.6 # MIT
tzdata>=2022.4 # MIT