diff --git a/datetime_tz/__init__.py b/datetime_tz/__init__.py index e939a56..8947c29 100644 --- a/datetime_tz/__init__.py +++ b/datetime_tz/__init__.py @@ -41,6 +41,7 @@ import os.path import re import sys +import struct import time import warnings import dateutil.parser @@ -256,7 +257,11 @@ def _detect_timezone_etc_timezone(): def _load_local_tzinfo(): """Load zoneinfo from local disk.""" - tzdir = os.environ.get("TZDIR", "/usr/share/zoneinfo/posix") + if os.path.exists("/usr/share/zoneinfo/posix"): + _tzdir = "/usr/share/zoneinfo/posix" + else: + _tzdir = "/usr/share/zoneinfo" + tzdir = os.environ.get("TZDIR", _tzdir) localtzdata = {} for dirpath, _, filenames in os.walk(tzdir): @@ -264,9 +269,11 @@ def _load_local_tzinfo(): filepath = os.path.join(dirpath, filename) name = os.path.relpath(filepath, tzdir) - f = open(filepath, "rb") - tzinfo = pytz.tzfile.build_tzinfo(name, f) - f.close() + with open(filepath, "rb") as f: + try: + tzinfo = pytz.tzfile.build_tzinfo(name, f) + except (AssertionError, struct.error): + continue localtzdata[name] = tzinfo return localtzdata @@ -276,9 +283,8 @@ def _detect_timezone_etc_localtime(): """Detect timezone based on /etc/localtime file.""" matches = [] if os.path.exists("/etc/localtime"): - f = open("/etc/localtime", "rb") - localtime = pytz.tzfile.build_tzinfo("/etc/localtime", f) - f.close() + with open("/etc/localtime", "rb") as f: + localtime = pytz.tzfile.build_tzinfo("/etc/localtime", f) # We want to match against the local database because /etc/localtime will # be copied from that. Once we have found a name for /etc/localtime, we can diff --git a/tests.py b/tests.py index b790bfd..1b0ba7e 100644 --- a/tests.py +++ b/tests.py @@ -86,6 +86,10 @@ FMT = "%Y-%m-%d %H:%M:%S %Z%z" +if sys.platform == "darwin": + TZDIR_POSIX = "/usr/share/zoneinfo" +else: + TZDIR_POSIX = "/usr/share/zoneinfo/posix" # Older versions of pytz only have AmbiguousTimeError, while newer versions # throw NonExistentTimeError. @@ -307,7 +311,7 @@ def os_path_exists_fake(filename, os_path_exists=os.path.exists): os_walk = os.walk def os_walk_fake(dirname, *args, **kw): if dirname in ( - "/usr/share/zoneinfo/posix", + TZDIR_POSIX, ): return [ (dirname, ["Etc", "Australia"], []), @@ -323,13 +327,13 @@ def localtime_valid_fake(filename, *args, **kw): filename = os.path.join(os.path.dirname(__file__), localtime_file) if filename in ( - "/usr/share/zoneinfo/posix/Australia/Melbourne", - "/usr/share/zoneinfo/posix/Australia/Sydney", + os.path.join(TZDIR_POSIX, "Australia/Melbourne"), + os.path.join(TZDIR_POSIX, "Australia/Sydney"), ): filename = test_zonedata_sydney if filename in ( - "/usr/share/zoneinfo/posix/Etc/UTC", + os.path.join(TZDIR_POSIX, "Etc/UTC"), ): filename = os.path.join(os.path.dirname(__file__), "test_zonedata_utc")