Remove Python 3.8 support and replace pytz code

Python 3.8 is no longer part of the tested runtimes for 2024.2 [1]
because its EOL is coming soon.

Python >= 3.9 provides the zoneinfo module to manipulate timezones. This
change replaces the usage of pytz, which was an implicit dependency
recently removed from Horizon [2].

[1] https://governance.openstack.org/tc/reference/runtimes/2024.2.html
[2] https://review.opendev.org/c/openstack/horizon/+/921651

Change-Id: If1f6627047787ae1965d5e66a2e73ad539a44039
This commit is contained in:
Pierre Riteau 2024-09-12 09:07:50 +02:00
parent 9607e819b3
commit 0a4fc6a160
6 changed files with 22 additions and 22 deletions

@ -11,10 +11,10 @@
# under the License.
from datetime import datetime
from datetime import timezone
from itertools import chain
import json
import logging
from pytz import UTC
from blazar_dashboard import conf
from django.conf import settings
@ -209,4 +209,4 @@ def _parse_api_datestr(datestr):
dateobj = datetime.strptime(datestr, "%Y-%m-%dT%H:%M:%S.%f")
return dateobj.replace(tzinfo=UTC)
return dateobj.replace(tzinfo=timezone.utc)

@ -17,12 +17,12 @@ import datetime
import json
import logging
import re
from zoneinfo import ZoneInfo
from django.utils.translation import gettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import messages
from pytz import timezone
from blazar_dashboard import api
@ -213,20 +213,21 @@ class CreateForm(forms.SelfHandlingForm):
def clean(self):
cleaned_data = super(CreateForm, self).clean()
local = timezone(self.request.session.get(
local = ZoneInfo(self.request.session.get(
'django_timezone',
self.request.COOKIES.get('django_timezone', 'UTC')))
if cleaned_data['start_date']:
cleaned_data['start_date'] = local.localize(
cleaned_data['start_date'].replace(tzinfo=None)
).astimezone(timezone('UTC'))
start = cleaned_data['start_date']
start = start.replace(tzinfo=local).astimezone(
datetime.timezone.utc)
cleaned_data['start_date'] = start
else:
cleaned_data['start_date'] = datetime.datetime.utcnow()
if cleaned_data['end_date']:
cleaned_data['end_date'] = local.localize(
cleaned_data['end_date'].replace(tzinfo=None)
).astimezone(timezone('UTC'))
end = cleaned_data['end_date']
end = end.replace(tzinfo=local).astimezone(datetime.timezone.utc)
cleaned_data['end_date'] = end
else:
cleaned_data['end_date'] = (cleaned_data['start_date'] +
datetime.timedelta(days=1))

@ -14,6 +14,7 @@
# under the License.
from datetime import datetime
from datetime import timezone
from functools import partial
from django.template import defaultfilters as django_filters
@ -21,7 +22,6 @@ from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from horizon import tables
from horizon.utils import filters
import pytz
from blazar_dashboard import api
from blazar_dashboard import conf
@ -43,7 +43,7 @@ class UpdateLease(tables.LinkAction):
def allowed(self, request, lease):
if datetime.strptime(lease.end_date, '%Y-%m-%dT%H:%M:%S.%f').\
replace(tzinfo=pytz.utc) > datetime.now(pytz.utc):
replace(tzinfo=timezone.utc) > datetime.now(timezone.utc):
return True
return False

@ -11,10 +11,10 @@
# under the License.
from datetime import datetime
from datetime import timezone
from unittest import mock
from django.urls import reverse
import pytz
from blazar_dashboard import api
from blazar_dashboard.test import helpers as test
@ -92,8 +92,8 @@ class LeasesTests(test.TestCase):
@mock.patch.object(api.client, 'lease_create')
def test_create_lease_host_reservation(self, lease_create):
start_date = datetime(2030, 6, 27, 18, 0, tzinfo=pytz.utc)
end_date = datetime(2030, 6, 30, 18, 0, tzinfo=pytz.utc)
start_date = datetime(2030, 6, 27, 18, 0, tzinfo=timezone.utc)
end_date = datetime(2030, 6, 30, 18, 0, tzinfo=timezone.utc)
new_lease = self.leases.get(name='lease-1')
form_data = {
'name': 'lease-1',
@ -129,8 +129,8 @@ class LeasesTests(test.TestCase):
@mock.patch.object(api.client, 'lease_create')
def test_create_lease_instance_reservation(self, lease_create):
start_date = datetime(2030, 6, 27, 18, 0, tzinfo=pytz.utc)
end_date = datetime(2030, 6, 30, 18, 0, tzinfo=pytz.utc)
start_date = datetime(2030, 6, 27, 18, 0, tzinfo=timezone.utc)
end_date = datetime(2030, 6, 30, 18, 0, tzinfo=timezone.utc)
dummy_lease = {}
form_data = {
'name': 'lease-1',
@ -171,8 +171,8 @@ class LeasesTests(test.TestCase):
@mock.patch.object(api.client, 'lease_create')
def test_create_lease_client_error(self, lease_create):
start_date = datetime(2030, 6, 27, 18, 0, tzinfo=pytz.utc)
end_date = datetime(2030, 6, 30, 18, 0, tzinfo=pytz.utc)
start_date = datetime(2030, 6, 27, 18, 0, tzinfo=timezone.utc)
end_date = datetime(2030, 6, 30, 18, 0, tzinfo=timezone.utc)
form_data = {
'name': 'lease-1',
'start_date': start_date.strftime('%Y-%m-%d %H:%M'),

@ -6,7 +6,7 @@ description_file =
author = OpenStack
author_email = openstack-discuss@lists.openstack.org
home_page = https://docs.openstack.org/blazar-dashboard/latest/
python_requires = >=3.8
python_requires = >=3.9
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
@ -17,7 +17,6 @@ classifier =
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11

@ -1,5 +1,5 @@
[tox]
envlist = py38,pep8
envlist = py3,pep8
minversion = 3.18.0
ignore_basepython_conflict = True