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