diff --git a/changelog.d/1024.misc.rst b/changelog.d/1024.misc.rst new file mode 100644 index 000000000..d55f738f9 --- /dev/null +++ b/changelog.d/1024.misc.rst @@ -0,0 +1,2 @@ +Fixed tz.gettz() not returning local time when passed an empty string. +Reported by @labrys (gh issues #925, #926). Fixed by @ffe4 (gh pr #1024) \ No newline at end of file diff --git a/dateutil/test/property/test_tz_prop.py b/dateutil/test/property/test_tz_prop.py new file mode 100644 index 000000000..ec6d271dc --- /dev/null +++ b/dateutil/test/property/test_tz_prop.py @@ -0,0 +1,35 @@ +from datetime import datetime, timedelta + +import pytest +import six +from hypothesis import assume, given +from hypothesis import strategies as st + +from dateutil import tz as tz + +EPOCHALYPSE = datetime.fromtimestamp(2147483647) +NEGATIVE_EPOCHALYPSE = datetime.fromtimestamp(0) - timedelta(seconds=2147483648) + + +@pytest.mark.gettz +@pytest.mark.parametrize("gettz_arg", [None, ""]) +# TODO: Remove bounds when GH #590 is resolved +@given( + dt=st.datetimes( + min_value=NEGATIVE_EPOCHALYPSE, max_value=EPOCHALYPSE, timezones=st.just(tz.UTC), + ) +) +def test_gettz_returns_local(gettz_arg, dt): + act_tz = tz.gettz(gettz_arg) + if isinstance(act_tz, tz.tzlocal): + return + + dt_act = dt.astimezone(tz.gettz(gettz_arg)) + if six.PY2: + dt_exp = dt.astimezone(tz.tzlocal()) + else: + dt_exp = dt.astimezone() + + assert dt_act == dt_exp + assert dt_act.tzname() == dt_exp.tzname() + assert dt_act.utcoffset() == dt_exp.utcoffset() diff --git a/dateutil/test/test_tz.py b/dateutil/test/test_tz.py index 6cd8ea088..e5e4772d9 100644 --- a/dateutil/test/test_tz.py +++ b/dateutil/test/test_tz.py @@ -1079,6 +1079,15 @@ def testGettzCacheTzLocal(self): assert local1 is not local2 +@pytest.mark.gettz +def test_gettz_same_result_for_none_and_empty_string(): + local_from_none = tz.gettz() + local_from_empty_string = tz.gettz("") + assert local_from_none is not None + assert local_from_empty_string is not None + assert local_from_none == local_from_empty_string + + @pytest.mark.gettz @pytest.mark.parametrize('badzone', [ 'Fake.Region/Abcdefghijklmnop', # Violates several tz project name rules diff --git a/dateutil/tz/tz.py b/dateutil/tz/tz.py index af81e88e1..c67f56d46 100644 --- a/dateutil/tz/tz.py +++ b/dateutil/tz/tz.py @@ -1596,7 +1596,7 @@ def nocache(name=None): name = os.environ["TZ"] except KeyError: pass - if name is None or name == ":": + if name is None or name in ("", ":"): for filepath in TZFILES: if not os.path.isabs(filepath): filename = filepath