Skip to content

Commit

Permalink
Merge pull request #95 from jeremystretch/94-catch-ZoneInfoNotFoundError
Browse files Browse the repository at this point in the history
Fixes #94: Catch ZoneInfoNotFoundError exception when populating timezones
  • Loading branch information
mfogel committed Jun 17, 2023
2 parents 914e3ef + c5504d2 commit d1c3d75
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
24 changes: 24 additions & 0 deletions tests/test_field.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
from unittest import mock

import pytest
import pytz
from django.core.exceptions import ValidationError
from pytest_lazyfixture import lazy_fixture

from timezone_field import TimeZoneField


def test_get_default_pytz_tzs():
default_pytz_tzs = TimeZoneField().get_default_pytz_tzs()
assert [str(tz) for tz in default_pytz_tzs] == pytz.common_timezones


@pytest.mark.parametrize(
"pytz_common_tzs, output_tzs",
[
[pytz.common_timezones, pytz.common_timezones],
# covers when ZoneInfo can't handle something in pytz.common_timezones
# https://github.com/mfogel/django-timezone-field/pull/95/files
[pytz.common_timezones + ["DNE"], pytz.common_timezones],
],
)
def test_get_default_zoneinfo_tzs(pytz_common_tzs, output_tzs):
with mock.patch("pytz.common_timezones") as mock_common_timezones:
mock_common_timezones.__iter__.return_value = iter(pytz_common_tzs)
default_zoneinfo_tzs = TimeZoneField.get_default_zoneinfo_tzs()
assert [str(tz) for tz in default_zoneinfo_tzs] == output_tzs


@pytest.mark.django_db
@pytest.mark.parametrize(
"input_tz, output_tz",
Expand Down
19 changes: 16 additions & 3 deletions timezone_field/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,21 @@ class TimeZoneField(models.Field):
# NOTE: these defaults are excluded from migrations. If these are changed,
# existing migration files will need to be accomodated.
default_max_length = 63
default_pytz_tzs = [pytz.timezone(tz) for tz in pytz.common_timezones]
default_zoneinfo_tzs = [ZoneInfo(tz) for tz in pytz.common_timezones]

@staticmethod
def get_default_pytz_tzs():
return [pytz.timezone(tz) for tz in pytz.common_timezones]

@staticmethod
def get_default_zoneinfo_tzs():
default_zoneinfo_tzs = []
for tz in pytz.common_timezones:
try:
default_zoneinfo_tzs.append(ZoneInfo(tz))
except ZoneInfoNotFoundError:
# ZoneInfo does not yet exist for this timezone
pass
return default_zoneinfo_tzs

def __init__(self, *args, **kwargs):
# allow some use of positional args up until the args we customize
Expand All @@ -50,7 +63,7 @@ def __init__(self, *args, **kwargs):

self.use_pytz_explicit = kwargs.pop("use_pytz", None)
self.use_pytz = self.use_pytz_explicit if self.use_pytz_explicit is not None else use_pytz_default()
self.default_tzs = self.default_pytz_tzs if self.use_pytz else self.default_zoneinfo_tzs
self.default_tzs = self.get_default_pytz_tzs() if self.use_pytz else self.get_default_zoneinfo_tzs()

if "choices" in kwargs:
values, displays = zip(*kwargs["choices"])
Expand Down

0 comments on commit d1c3d75

Please sign in to comment.