Fix compatibility with Python 3.8

We removed compatibility with Python 3.8 once but it was added back to
tested runtimes for 2023.2. Thus we have to make sure the code works
with Python 3.8, which was broken by [1].

Note that pytz is added back to requirmenets.txt and is now required
regardless of the python version. This is a short term solution until
we figure out the way to fix the requirement-check job (or we again
remove python 3.8 support).

[1] a326ec5eea

Change-Id: I3b222bb59260dff7a06a5ed48720df3dc8c74ea7
This commit is contained in:
Hervé Beraud 2023-05-15 10:57:53 +02:00
parent d4c988ab9c
commit 61c460f3f2
4 changed files with 46 additions and 17 deletions

View File

@ -33,9 +33,16 @@ import functools
import itertools
import uuid
from xmlrpc import client as xmlrpclib
import zoneinfo
import msgpack
try:
import zoneinfo
except ImportError:
# zoneinfo is available in Python >= 3.9
from pytz import timezone
zoneinfo = None
from oslo_utils import importutils
netaddr = importutils.try_import("netaddr")
@ -236,7 +243,10 @@ class DateTimeHandler(object):
'microsecond': dt.microsecond,
}
if dt.tzinfo:
tz = str(dt.tzinfo)
if zoneinfo:
tz = str(dt.tzinfo)
else:
tz = dt.tzinfo.tzname(None)
dct['tz'] = tz
return dumps(dct, registry=self._registry)
@ -264,8 +274,12 @@ class DateTimeHandler(object):
second=dct['second'],
microsecond=dct['microsecond'])
if 'tz' in dct and dct['tz']:
tzinfo = zoneinfo.ZoneInfo(dct['tz'])
dt = dt.replace(tzinfo=tzinfo)
if zoneinfo:
tzinfo = zoneinfo.ZoneInfo(dct['tz'])
dt = dt.replace(tzinfo=tzinfo)
else:
tzinfo = timezone(dct['tz'])
dt = tzinfo.localize(dt)
return dt

View File

@ -15,11 +15,17 @@
import datetime
import itertools
from xmlrpc import client as xmlrpclib
import zoneinfo
import netaddr
from oslotest import base as test_base
try:
import zoneinfo
except ImportError:
# zoneinfo is available in Python >= 3.9
from pytz import timezone
zoneinfo = None
from oslo_serialization import msgpackutils
from oslo_utils import uuidutils
@ -145,22 +151,31 @@ class MsgPackUtilsTest(test_base.BaseTestCase):
self.assertEqual(today, _dumps_loads(today))
def test_datetime_tz_clone(self):
eastern = zoneinfo.ZoneInfo('US/Eastern')
now = datetime.datetime.now()
e_dt = now.replace(tzinfo=eastern)
if zoneinfo:
eastern = zoneinfo.ZoneInfo('US/Eastern')
e_dt = now.replace(tzinfo=eastern)
else:
eastern = timezone('US/Eastern')
e_dt = eastern.localize(now)
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 = zoneinfo.ZoneInfo('US/Eastern')
pacific = zoneinfo.ZoneInfo('US/Pacific')
now = datetime.datetime.now()
now = now.replace(tzinfo=eastern)
e_dt = now
now = now.replace(tzinfo=pacific)
p_dt = now
if zoneinfo:
eastern = zoneinfo.ZoneInfo('US/Eastern')
pacific = zoneinfo.ZoneInfo('US/Pacific')
now = now.replace(tzinfo=eastern)
e_dt = now
now = now.replace(tzinfo=pacific)
p_dt = now
else:
eastern = timezone('US/Eastern')
pacific = timezone('US/Pacific')
e_dt = eastern.localize(now)
p_dt = pacific.localize(now)
self.assertNotEqual(e_dt, p_dt)
self.assertNotEqual(e_dt.strftime(_TZ_FMT), p_dt.strftime(_TZ_FMT))

View File

@ -1,6 +1,5 @@
---
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.
Implement zoneinfo to allow us to remove pytz's dependency for Python 3.9
and 3.10

View File

@ -10,4 +10,5 @@
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