From 61c460f3f27e00e080faad479342127e8442314d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Beraud?= Date: Mon, 15 May 2023 10:57:53 +0200 Subject: [PATCH] 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] a326ec5eea86d7458953a229b4dbd887595f68f1 Change-Id: I3b222bb59260dff7a06a5ed48720df3dc8c74ea7 --- oslo_serialization/msgpackutils.py | 22 +++++++++--- oslo_serialization/tests/test_msgpackutils.py | 35 +++++++++++++------ ...einfo-to-remove-pytz-c136b33bbfbfe59f.yaml | 5 ++- requirements.txt | 1 + 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/oslo_serialization/msgpackutils.py b/oslo_serialization/msgpackutils.py index 01003bf..e71a123 100644 --- a/oslo_serialization/msgpackutils.py +++ b/oslo_serialization/msgpackutils.py @@ -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 diff --git a/oslo_serialization/tests/test_msgpackutils.py b/oslo_serialization/tests/test_msgpackutils.py index 3acc70d..7558532 100644 --- a/oslo_serialization/tests/test_msgpackutils.py +++ b/oslo_serialization/tests/test_msgpackutils.py @@ -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)) diff --git a/releasenotes/notes/implement-zoneinfo-to-remove-pytz-c136b33bbfbfe59f.yaml b/releasenotes/notes/implement-zoneinfo-to-remove-pytz-c136b33bbfbfe59f.yaml index 24c7d7f..167f040 100644 --- a/releasenotes/notes/implement-zoneinfo-to-remove-pytz-c136b33bbfbfe59f.yaml +++ b/releasenotes/notes/implement-zoneinfo-to-remove-pytz-c136b33bbfbfe59f.yaml @@ -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 diff --git a/requirements.txt b/requirements.txt index d31beef..b8be88c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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