Remove pytz dependency

Use built-in zoneinfo lib which was introduced
in Python 3.9.

Adds a requirement on tzdata to ensure that tzdata is
installed if not provided by the system.

See more details in
https://review.opendev.org/c/openstack/requirements/+/875854

Change-Id: If4b711c45ca8a4ec3ec13623597739cc095c0352
This commit is contained in:
Eric Harney 2023-05-04 11:40:51 -04:00 committed by Takashi Kajinami
parent e9c18c7f94
commit 7afc7ae2ac
13 changed files with 46 additions and 37 deletions

View File

@ -22,13 +22,13 @@ from __future__ import annotations
from datetime import datetime
import random
from typing import Optional
from zoneinfo import ZoneInfo
from eventlet import greenthread
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import strutils
from pytz import timezone
from cinder.backup import rpcapi as backup_rpcapi
from cinder.common import constants
@ -301,7 +301,7 @@ class API(base.Base):
if (x['status'] == fields.BackupStatus.AVAILABLE and (
not snapshot or (snapshot and x['data_timestamp']
< snapshot['created_at'])))
else datetime(1, 1, 1, 1, 1, 1, tzinfo=timezone('UTC')))
else datetime(1, 1, 1, 1, 1, 1, tzinfo=ZoneInfo('UTC')))
else:
QUOTAS.rollback(context, reservations)
msg = _('No backups available to do an incremental backup.')

View File

@ -13,11 +13,11 @@
# under the License.
from typing import Optional
from zoneinfo import ZoneInfo
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import timeutils
from pytz import timezone
from cinder import context
from cinder import objects
@ -114,7 +114,7 @@ class ImageVolumeCache(object):
if isinstance(image_updated_at, str):
image_updated_at = timeutils.parse_strtime(image_updated_at)
else:
image_updated_at = image_updated_at.astimezone(timezone('UTC'))
image_updated_at = image_updated_at.astimezone(ZoneInfo('UTC'))
cache_entry = self.db.image_volume_cache_create(
context,
@ -252,9 +252,9 @@ class ImageVolumeCache(object):
image_meta: dict) -> bool:
"""Ensure that the cache entry image data is still valid."""
image_updated_utc = (image_meta['updated_at']
.astimezone(timezone('UTC')))
.astimezone(ZoneInfo('UTC')))
cache_updated_utc = (cache_entry['image_updated_at']
.replace(tzinfo=timezone('UTC')))
.replace(tzinfo=ZoneInfo('UTC')))
LOG.debug('Image-volume cache entry image_update_at = %(entry_utc)s, '
'requested image updated_at = %(image_utc)s.',

View File

@ -17,10 +17,10 @@ import datetime
from http import HTTPStatus
from unittest import mock
from urllib import parse as urllib
from zoneinfo import ZoneInfo
import ddt
from oslo_config import cfg
import pytz
import webob
from cinder.api import common
@ -269,7 +269,7 @@ class SnapshotApiTest(test.TestCase):
'status': fields.SnapshotStatus.AVAILABLE,
'size': 100,
'created_at': datetime.datetime(2014, 1, 1, 0, 0, 0,
tzinfo=pytz.utc),
tzinfo=ZoneInfo('UTC')),
'updated_at': None,
'name': u'Updated Test Name',
'description': u'Default description',
@ -376,7 +376,7 @@ class SnapshotApiTest(test.TestCase):
'status': fields.SnapshotStatus.AVAILABLE,
'size': 100,
'created_at': datetime.datetime(2018, 1, 14, 0, 0, 0,
tzinfo=pytz.utc),
tzinfo=ZoneInfo('UTC')),
'updated_at': None,
'name': u'test',
'description': u'test',

View File

@ -13,9 +13,9 @@
# under the License.
from unittest import mock
from zoneinfo import ZoneInfo
from oslo_utils import timeutils
import pytz
from cinder.db.sqlalchemy import models
from cinder import exception
@ -118,8 +118,9 @@ class TestBackup(test_objects.BaseObjectsTestCase):
self.assertTrue(admin_context.is_admin)
self.assertTrue(backup.deleted)
self.assertEqual(fields.BackupStatus.DELETED, backup.status)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
backup.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
backup.deleted_at)
def test_obj_field_temp_volume_snapshot_id(self):
backup = objects.Backup(context=self.context,

View File

@ -13,9 +13,9 @@
# under the License.
from unittest import mock
from zoneinfo import ZoneInfo
from oslo_utils import timeutils
import pytz
from cinder import exception
from cinder import objects
@ -98,8 +98,9 @@ class TestCGSnapshot(test_objects.BaseObjectsTestCase):
self.assertTrue(admin_context.is_admin)
self.assertTrue(cgsnapshot.deleted)
self.assertEqual('deleted', cgsnapshot.status)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
cgsnapshot.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
cgsnapshot.deleted_at)
@mock.patch('cinder.objects.consistencygroup.ConsistencyGroup.get_by_id')
@mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot')

View File

@ -13,9 +13,9 @@
# under the License.
from unittest import mock
from zoneinfo import ZoneInfo
from oslo_utils import timeutils
import pytz
from cinder import exception
from cinder import objects
@ -194,8 +194,9 @@ class TestConsistencyGroup(test_objects.BaseObjectsTestCase):
self.assertTrue(consistencygroup.deleted)
self.assertEqual(fields.ConsistencyGroupStatus.DELETED,
consistencygroup.status)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
consistencygroup.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
consistencygroup.deleted_at)
@mock.patch('cinder.db.sqlalchemy.api.consistencygroup_get')
def test_refresh(self, consistencygroup_get):

View File

@ -13,9 +13,9 @@
# under the License.
from unittest import mock
from zoneinfo import ZoneInfo
from oslo_utils import timeutils
import pytz
from cinder import exception
from cinder import objects
@ -103,8 +103,9 @@ class TestGroupSnapshot(test_objects.BaseObjectsTestCase):
self.assertTrue(group_snapshot.deleted)
self.assertEqual(fields.GroupSnapshotStatus.DELETED,
group_snapshot.status)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
group_snapshot.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
group_snapshot.deleted_at)
@mock.patch('cinder.objects.group.Group.get_by_id')
@mock.patch(

View File

@ -11,9 +11,9 @@
# under the License.
from unittest import mock
from zoneinfo import ZoneInfo
from oslo_utils import timeutils
import pytz
from cinder.db.sqlalchemy import models
from cinder import exception
@ -97,8 +97,9 @@ class TestQos(test_objects.BaseObjectsTestCase):
qos_fake_delete.assert_called_once_with(mock.ANY, fake_qos['id'])
self.assertTrue(qos_object.deleted)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
qos_object.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
qos_object.deleted_at)
@mock.patch('cinder.db.sqlalchemy.api.qos_specs_delete')
@mock.patch('cinder.db.qos_specs_disassociate_all')

View File

@ -14,10 +14,10 @@
import datetime
from unittest import mock
from zoneinfo import ZoneInfo
import ddt
from oslo_utils import timeutils
import pytz
from cinder import exception
from cinder import objects
@ -92,8 +92,9 @@ class TestService(test_objects.BaseObjectsTestCase):
service.destroy()
service_destroy.assert_called_once_with(elevated_ctx(), 123)
self.assertTrue(service.deleted)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
service.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
service.deleted_at)
@mock.patch('cinder.db.sqlalchemy.api.service_get')
def test_refresh(self, service_get):

View File

@ -14,10 +14,10 @@
import copy
from unittest import mock
from zoneinfo import ZoneInfo
import ddt
from oslo_utils import timeutils
import pytz
from cinder.db.sqlalchemy import models
from cinder import exception
@ -131,8 +131,9 @@ class TestSnapshot(test_objects.BaseObjectsTestCase):
self.assertTrue(admin_context.is_admin)
self.assertTrue(snapshot.deleted)
self.assertEqual(fields.SnapshotStatus.DELETED, snapshot.status)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
snapshot.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
snapshot.deleted_at)
@mock.patch('cinder.db.snapshot_metadata_delete')
def test_delete_metadata_key(self, snapshot_metadata_delete):

View File

@ -13,10 +13,10 @@
# under the License.
from unittest import mock
from zoneinfo import ZoneInfo
import ddt
from oslo_utils import timeutils
import pytz
from cinder import context
from cinder import exception
@ -177,8 +177,9 @@ class TestVolume(test_objects.BaseObjectsTestCase):
self.assertTrue(admin_context.is_admin)
self.assertTrue(volume.deleted)
self.assertEqual('deleted', volume.status)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
volume.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
volume.deleted_at)
self.assertIsNone(volume.migration_status)
def test_obj_fields(self):

View File

@ -13,10 +13,10 @@
# under the License.
from unittest import mock
from zoneinfo import ZoneInfo
import ddt
from oslo_utils import timeutils
import pytz
from cinder import db
from cinder.db.sqlalchemy import models
@ -123,8 +123,9 @@ class TestVolumeType(test_objects.BaseObjectsTestCase):
admin_context = volume_type_destroy.call_args[0][0]
self.assertTrue(admin_context.is_admin)
self.assertTrue(volume_type.deleted)
self.assertEqual(utcnow_mock.return_value.replace(tzinfo=pytz.UTC),
volume_type.deleted_at)
self.assertEqual(
utcnow_mock.return_value.replace(tzinfo=ZoneInfo('UTC')),
volume_type.deleted_at)
@mock.patch('cinder.db.sqlalchemy.api._volume_type_get_full')
def test_refresh(self, volume_type_get):

View File

@ -41,7 +41,6 @@ python-glanceclient>=3.2.2 # Apache-2.0
python-keystoneclient>=4.1.1 # Apache-2.0
python-novaclient>=18.2.0 # Apache-2.0
python-swiftclient>=3.10.1 # Apache-2.0
pytz>=2020.1 # MIT
requests>=2.25.1 # Apache-2.0
Routes>=2.4.1 # MIT
taskflow>=4.5.0 # Apache-2.0
@ -64,3 +63,4 @@ cursive>=0.2.2 # Apache-2.0
zstd>=1.4.5.1 # BSD
boto3>=1.18.49 # Apache-2.0
distro>=1.8.0 # Apache-2.0
tzdata>=2022.4 # MIT