diff --git a/lib/tzlocal/CHANGES.txt b/lib/tzlocal/CHANGES.txt deleted file mode 100644 index 43e9f35b..00000000 --- a/lib/tzlocal/CHANGES.txt +++ /dev/null @@ -1,189 +0,0 @@ -Changes -======= - -2.1b1 (2020-02-08) ------------------- - -- The is_dst flag is wrong for Europe/Dublin on some Unix releases. - I changed to another way of determining if DST is in effect or not. - -- Added support for Python 3.7 and 3.8. Dropped 3.5 although it still works. - - -2.0.0 (2019-07-23) ------------------- - -- No differences since 2.0.0b3 - -Major differences since 1.5.1 -............................. - -- When no time zone configuration can be find, tzlocal now return UTC. - This is a major difference from 1.x, where an exception would be raised. - This change is because Docker images often have no configuration at all, - and the unix utilities will then default to UTC, so we follow that. - -- If tzlocal on Unix finds a timezone name in a /etc config file, then - tzlocal now verifies that the timezone it fouds has the same offset as - the local computer is configured with. If it doesn't, something is - configured incorrectly. (Victor Torres, regebro) - -- Get timezone via Termux `getprop` wrapper on Android. It's not officially - supported because we can't test it, but at least we make an effort. - (Jean Jordaan) - -Minor differences and bug fixes -............................... - -- Skip comment lines when parsing /etc/timezone. (Edward Betts) - -- Don't load timezone from current directory. (Gabriel Corona) - -- Now verifies that the config files actually contain something before - reading them. (Zackary Welch, regebro) - -- Got rid of a BytesWarning (Mickaƫl Schoentgen) - -- Now handles if config file paths exists, but are directories. - -- Moved tests out from distributions - -- Support wheels - - -1.5.1 (2017-12-01) ------------------- - -- 1.5 had a bug that slipped through testing, fixed that, - increased test coverage. - - -1.5 (2017-11-30) ----------------- - -- No longer treats macOS as special, but as a unix. - -- get_windows_info.py is renamed to update_windows_mappings.py - -- Windows mappings now also contain mappings from deprecated zoneinfo names. - (Preston-Landers, regebro) - - -1.4 (2017-04-18) ----------------- - -- I use MIT on my other projects, so relicensing. - - -1.4b1 (2017-04-14) ------------------- - -- Dropping support for Python versions nobody uses (2.5, 3.1, 3.2), adding 3.6 - Python 3.1 and 3.2 still works, 2.5 has been broken for some time. - -- Ayalash's OS X fix didn't work on Python 2.7, fixed that. - - -1.3.2 (2017-04-12) ------------------- - -- Ensure closing of subprocess on OS X (ayalash) - -- Removed unused imports (jwilk) - -- Closes stdout and stderr to get rid of ResourceWarnings (johnwquarles) - -- Updated Windows timezones (axil) - - -1.3 (2016-10-15) ----------------- - -- #34: Added support for /var/db/zoneinfo - - -1.2.2 (2016-03-02) ------------------- - -- #30: Fixed a bug on OS X. - - -1.2.1 (2016-02-28) ------------------- - -- Tests failed if TZ was set in the environment. (EdwardBetts) - -- Replaces os.popen() with subprocess.Popen() for OS X to - handle when systemsetup doesn't exist. (mckabi, cewing) - - -1.2 (2015-06-14) ----------------- - -- Systemd stores no time zone name, forcing us to look at the name of the file - that localtime symlinks to. (cameris) - - -1.1.2 (2014-10-18) ------------------- - -- Timezones that has 3 items did not work on Mac OS X. - (Marc Van Olmen) - -- Now doesn't fail if the TZ environment variable isn't an Olsen time zone. - -- Some timezones on Windows can apparently be empty (perhaps the are deleted). - Now these are ignored. - (Xiaokun Zhu) - - -1.1.1 (2014-01-29) ------------------- - -- I forgot to add Etc/UTC as an alias for Etc/GMT. - - -1.1 (2014-01-28) ----------------- - -- Adding better support for OS X. - -- Added support to map from tzdata/Olsen names to Windows names. - (Thanks to Benjamen Meyer). - - -1.0 (2013-05-29) ----------------- - -- Fixed some more cases where spaces needs replacing with underscores. - -- Better handling of misconfigured /etc/timezone. - -- Better error message on Windows if we can't find a timezone at all. - - -0.3 (2012-09-13) ----------------- - -- Windows 7 support. - -- Python 2.5 supported; because it only needed a __future__ import. - -- Python 3.3 tested, it worked. - -- Got rid of relative imports, because I don't actually like them, - so I don't know why I used them in the first place. - -- For each Windows zone, use the default zoneinfo zone, not the last one. - - -0.2 (2012-09-12) ----------------- - -- Python 3 support. - - -0.1 (2012-09-11) ----------------- - -- Initial release. diff --git a/lib/tzlocal/LICENSE.txt b/lib/tzlocal/LICENSE.txt deleted file mode 100644 index 9be1d2fe..00000000 --- a/lib/tzlocal/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright 2011-2017 Lennart Regebro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/lib/tzlocal/unix.py b/lib/tzlocal/unix.py index 8574965a..4999eb5b 100644 --- a/lib/tzlocal/unix.py +++ b/lib/tzlocal/unix.py @@ -1,10 +1,16 @@ import os -import pytz import re +import sys import warnings +from datetime import timezone from tzlocal import utils +if sys.version_info >= (3, 9): + from zoneinfo import ZoneInfo, ZoneInfoNotFoundError +else: + from backports.zoneinfo import ZoneInfo, ZoneInfoNotFoundError + _cache_tz = None @@ -15,17 +21,17 @@ def _tz_from_env(tzenv): # TZ specifies a file if os.path.isabs(tzenv) and os.path.exists(tzenv): with open(tzenv, 'rb') as tzfile: - return pytz.tzfile.build_tzinfo('local', tzfile) + return ZoneInfo.from_file(tzfile, key='local') # TZ specifies a zoneinfo zone. try: - tz = pytz.timezone(tzenv) + tz = ZoneInfo(tzenv) # That worked, so we return this: return tz - except pytz.UnknownTimeZoneError: - raise pytz.UnknownTimeZoneError( + except ZoneInfoNotFoundError: + raise ZoneInfoNotFoundError( "tzlocal() does not support non-zoneinfo timezones like %s. \n" - "Please use a timezone in the form of Continent/City") + "Please use a timezone in the form of Continent/City") from None def _try_tz_from_env(): @@ -33,7 +39,7 @@ def _try_tz_from_env(): if tzenv: try: return _tz_from_env(tzenv) - except pytz.UnknownTimeZoneError: + except ZoneInfoNotFoundError: pass @@ -56,7 +62,7 @@ def _get_localzone(_root='/'): if os.path.exists('/system/bin/getprop'): import subprocess androidtz = subprocess.check_output(['getprop', 'persist.sys.timezone']).strip().decode() - return pytz.timezone(androidtz) + return ZoneInfo(androidtz) # Now look for distribution specific configuration files # that contain the timezone name. @@ -83,15 +89,15 @@ def _get_localzone(_root='/'): etctz, dummy = etctz.split('#', 1) if not etctz: continue - tz = pytz.timezone(etctz.replace(' ', '_')) + tz = ZoneInfo(etctz.replace(' ', '_')) if _root == '/': # We are using a file in etc to name the timezone. # Verify that the timezone specified there is actually used: utils.assert_tz_offset(tz) return tz - except IOError: - # File doesn't exist or is a directory + except (IOError, UnicodeDecodeError): + # File doesn't exist or is a directory, or it's a binary file. continue # CentOS has a ZONE setting in /etc/sysconfig/clock, @@ -121,15 +127,15 @@ def _get_localzone(_root='/'): etctz = line[:end_re.search(line).start()] # We found a timezone - tz = pytz.timezone(etctz.replace(' ', '_')) + tz = ZoneInfo(etctz.replace(' ', '_')) if _root == '/': # We are using a file in etc to name the timezone. # Verify that the timezone specified there is actually used: utils.assert_tz_offset(tz) return tz - except IOError: - # File doesn't exist or is a directory + except (IOError, UnicodeDecodeError) as e: + # UnicodeDecode handles when clock is symlink to /etc/localtime continue # systemd distributions use symlinks that include the zone name, @@ -141,8 +147,8 @@ def _get_localzone(_root='/'): while start != 0: tzpath = tzpath[start:] try: - return pytz.timezone(tzpath) - except pytz.UnknownTimeZoneError: + return ZoneInfo(tzpath) + except ZoneInfoNotFoundError: pass start = tzpath.find("/")+1 @@ -153,10 +159,10 @@ def _get_localzone(_root='/'): if not os.path.exists(tzpath): continue with open(tzpath, 'rb') as tzfile: - return pytz.tzfile.build_tzinfo('local', tzfile) + return ZoneInfo.from_file(tzfile, key='local') warnings.warn('Can not find any timezone configuration, defaulting to UTC.') - return pytz.utc + return timezone.utc def get_localzone(): """Get the computers configured local timezone, if any.""" diff --git a/lib/tzlocal/win32.py b/lib/tzlocal/win32.py index fcc42a23..0472a7c8 100644 --- a/lib/tzlocal/win32.py +++ b/lib/tzlocal/win32.py @@ -1,13 +1,18 @@ +import sys + try: import _winreg as winreg except ImportError: import winreg -import pytz - from tzlocal.windows_tz import win_tz from tzlocal import utils +if sys.version_info >= (3, 9): + from zoneinfo import ZoneInfo, ZoneInfoNotFoundError +else: + from backports.zoneinfo import ZoneInfo, ZoneInfoNotFoundError + _cache_tz = None @@ -81,7 +86,7 @@ def get_localzone_name(): # Return what we have. if timezone is None: - raise pytz.UnknownTimeZoneError('Can not find timezone ' + tzkeyname) + raise ZoneInfoNotFoundError(tzkeyname) return timezone @@ -90,7 +95,7 @@ def get_localzone(): """Returns the zoneinfo-based tzinfo object that matches the Windows-configured timezone.""" global _cache_tz if _cache_tz is None: - _cache_tz = pytz.timezone(get_localzone_name()) + _cache_tz = ZoneInfo(get_localzone_name()) utils.assert_tz_offset(_cache_tz) return _cache_tz @@ -99,6 +104,6 @@ def get_localzone(): def reload_localzone(): """Reload the cached localzone. You need to call this if the timezone has changed.""" global _cache_tz - _cache_tz = pytz.timezone(get_localzone_name()) + _cache_tz = ZoneInfo(get_localzone_name()) utils.assert_tz_offset(_cache_tz) return _cache_tz