Fixed #18766 -- Pointed to pytz when LocalTimezone fails.

Thanks void for the report.
This commit is contained in:
Aymeric Augustin 2013-09-07 18:56:49 -05:00
parent b11564fd36
commit ded11aa620
2 changed files with 30 additions and 2 deletions

View File

@ -1,10 +1,12 @@
"""Timezone helper functions. """
Timezone-related classes and functions.
This module uses pytz when it's available and fallbacks when it isn't. This module uses pytz when it's available and fallbacks when it isn't.
""" """
from datetime import datetime, timedelta, tzinfo from datetime import datetime, timedelta, tzinfo
from threading import local from threading import local
import sys
import time as _time import time as _time
try: try:
@ -45,12 +47,14 @@ class UTC(tzinfo):
def dst(self, dt): def dst(self, dt):
return ZERO return ZERO
class LocalTimezone(tzinfo): class ReferenceLocalTimezone(tzinfo):
""" """
Local time implementation taken from Python's docs. Local time implementation taken from Python's docs.
Used only when pytz isn't available, and most likely inaccurate. If you're Used only when pytz isn't available, and most likely inaccurate. If you're
having trouble with this class, don't waste your time, just install pytz. having trouble with this class, don't waste your time, just install pytz.
Kept identical to the reference version. Subclasses contain improvements.
""" """
def __init__(self): def __init__(self):
@ -91,6 +95,23 @@ class LocalTimezone(tzinfo):
tt = _time.localtime(stamp) tt = _time.localtime(stamp)
return tt.tm_isdst > 0 return tt.tm_isdst > 0
class LocalTimezone(ReferenceLocalTimezone):
"""
Slightly improved local time implementation focusing on correctness.
It still crashes on dates before 1970 or after 2038, but at least the
error message is helpful.
"""
def _isdst(self, dt):
try:
return super(LocalTimezone, self)._isdst(dt)
except (OverflowError, ValueError) as exc:
exc_type = type(exc)
exc_value = exc_type(
"Unsupported value: %r. You should install pytz." % dt)
exc_value.__cause__ = exc
six.reraise(exc_type, exc_value, sys.exc_info()[2])
utc = pytz.utc if pytz else UTC() utc = pytz.utc if pytz else UTC()
"""UTC time zone as a tzinfo instance.""" """UTC time zone as a tzinfo instance."""

View File

@ -4,6 +4,7 @@ import pickle
import unittest import unittest
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils import six
from django.utils import timezone from django.utils import timezone
from django.utils.tzinfo import FixedOffset from django.utils.tzinfo import FixedOffset
@ -20,6 +21,12 @@ class TimezoneTests(unittest.TestCase):
local_now = timezone.localtime(now, local_tz) local_now = timezone.localtime(now, local_tz)
self.assertEqual(local_now.tzinfo, local_tz) self.assertEqual(local_now.tzinfo, local_tz)
def test_localtime_out_of_range(self):
local_tz = timezone.LocalTimezone()
long_ago = datetime.datetime(1900, 1, 1, tzinfo=timezone.utc)
with six.assertRaisesRegex(self, OverflowError, "install pytz"):
timezone.localtime(long_ago, local_tz)
def test_now(self): def test_now(self):
with override_settings(USE_TZ=True): with override_settings(USE_TZ=True):
self.assertTrue(timezone.is_aware(timezone.now())) self.assertTrue(timezone.is_aware(timezone.now()))