Revert "Bump apscheduler from 3.10.1 to 3.10.4 (#2133)"

This reverts commit 2c42150799.
This commit is contained in:
dependabot[bot] 2023-08-24 12:10:08 -07:00 committed by JonnyWong16
commit 80e6131a0d
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
11 changed files with 825 additions and 855 deletions

View file

@ -9,12 +9,5 @@ if sys.platform == "win32":
else:
from tzlocal.unix import get_localzone, get_localzone_name, reload_localzone
from tzlocal.utils import assert_tz_offset
__all__ = [
"get_localzone",
"get_localzone_name",
"reload_localzone",
"assert_tz_offset",
]
__all__ = ["get_localzone", "get_localzone_name", "reload_localzone"]

View file

@ -1,21 +1,20 @@
import logging
import os
import re
import sys
import warnings
from datetime import timezone
import pytz_deprecation_shim as pds
from tzlocal import utils
if sys.version_info >= (3, 9):
import zoneinfo # pragma: no cover
from zoneinfo import ZoneInfo # pragma: no cover
else:
from backports import zoneinfo # pragma: no cover
from backports.zoneinfo import ZoneInfo # pragma: no cover
_cache_tz = None
_cache_tz_name = None
log = logging.getLogger("tzlocal")
def _get_localzone_name(_root="/"):
"""Tries to find the local timezone configuration.
@ -33,21 +32,14 @@ def _get_localzone_name(_root="/"):
# Are we under Termux on Android?
if os.path.exists(os.path.join(_root, "system/bin/getprop")):
log.debug("This looks like Termux")
import subprocess
try:
androidtz = (
subprocess.check_output(["getprop", "persist.sys.timezone"])
.strip()
.decode()
)
return androidtz
except (OSError, subprocess.CalledProcessError):
# proot environment or failed to getprop
log.debug("It's not termux?")
pass
androidtz = (
subprocess.check_output(["getprop", "persist.sys.timezone"])
.strip()
.decode()
)
return androidtz
# Now look for distribution specific configuration files
# that contain the timezone name.
@ -58,11 +50,10 @@ def _get_localzone_name(_root="/"):
for configfile in ("etc/timezone", "var/db/zoneinfo"):
tzpath = os.path.join(_root, configfile)
try:
with open(tzpath) as tzfile:
with open(tzpath, "rt") as tzfile:
data = tzfile.read()
log.debug(f"{tzpath} found, contents:\n {data}")
etctz = data.strip("/ \t\r\n")
etctz = data.strip('/ \t\r\n')
if not etctz:
# Empty file, skip
continue
@ -77,7 +68,7 @@ def _get_localzone_name(_root="/"):
found_configs[tzpath] = etctz.replace(" ", "_")
except (OSError, UnicodeDecodeError):
except (IOError, UnicodeDecodeError):
# File doesn't exist or is a directory, or it's a binary file.
continue
@ -95,7 +86,6 @@ def _get_localzone_name(_root="/"):
try:
with open(tzpath, "rt") as tzfile:
data = tzfile.readlines()
log.debug(f"{tzpath} found, contents:\n {data}")
for line in data:
# Look for the ZONE= setting.
@ -105,13 +95,13 @@ def _get_localzone_name(_root="/"):
match = timezone_re.match(line)
if match is not None:
# Some setting existed
line = line[match.end() :]
line = line[match.end():]
etctz = line[: end_re.search(line).start()]
# We found a timezone
found_configs[tzpath] = etctz.replace(" ", "_")
except (OSError, UnicodeDecodeError):
except (IOError, UnicodeDecodeError):
# UnicodeDecode handles when clock is symlink to /etc/localtime
continue
@ -119,34 +109,30 @@ def _get_localzone_name(_root="/"):
# see manpage of localtime(5) and timedatectl(1)
tzpath = os.path.join(_root, "etc/localtime")
if os.path.exists(tzpath) and os.path.islink(tzpath):
log.debug(f"{tzpath} found")
etctz = os.path.realpath(tzpath)
etctz = realtzpath = os.path.realpath(tzpath)
start = etctz.find("/") + 1
while start != 0:
etctz = etctz[start:]
try:
zoneinfo.ZoneInfo(etctz)
pds.timezone(etctz)
tzinfo = f"{tzpath} is a symlink to"
found_configs[tzinfo] = etctz.replace(" ", "_")
# Only need first valid relative path in simlink.
break
except zoneinfo.ZoneInfoNotFoundError:
except pds.UnknownTimeZoneError:
pass
start = etctz.find("/") + 1
if len(found_configs) > 0:
log.debug(f"{len(found_configs)} found:\n {found_configs}")
# We found some explicit config of some sort!
if len(found_configs) > 1:
# Uh-oh, multiple configs. See if they match:
unique_tzs = set()
zoneinfopath = os.path.join(_root, "usr", "share", "zoneinfo")
directory_depth = len(zoneinfopath.split(os.path.sep))
zoneinfo = os.path.join(_root, "usr", "share", "zoneinfo")
directory_depth = len(zoneinfo.split(os.path.sep))
for tzname in found_configs.values():
# Look them up in /usr/share/zoneinfo, and find what they
# really point to:
path = os.path.realpath(os.path.join(zoneinfopath, *tzname.split("/")))
path = os.path.realpath(os.path.join(zoneinfo, *tzname.split("/")))
real_zone_name = "/".join(path.split(os.path.sep)[directory_depth:])
unique_tzs.add(real_zone_name)
@ -155,7 +141,7 @@ def _get_localzone_name(_root="/"):
for key, value in found_configs.items():
message += f"{key}: {value}\n"
message += "Fix the configuration, or set the time zone in a TZ environment variable.\n"
raise zoneinfo.ZoneInfoNotFoundError(message)
raise utils.ZoneInfoNotFoundError(message)
# We found exactly one config! Use it.
return list(found_configs.values())[0]
@ -179,25 +165,24 @@ def _get_localzone(_root="/"):
tzname = _get_localzone_name(_root)
if tzname is None:
# No explicit setting existed. Use localtime
log.debug("No explicit setting existed. Use localtime")
for filename in ("etc/localtime", "usr/local/etc/localtime"):
tzpath = os.path.join(_root, filename)
if not os.path.exists(tzpath):
continue
with open(tzpath, "rb") as tzfile:
tz = zoneinfo.ZoneInfo.from_file(tzfile, key="local")
tz = pds.wrap_zone(ZoneInfo.from_file(tzfile, key="local"))
break
else:
warnings.warn("Can not find any timezone configuration, defaulting to UTC.")
tz = timezone.utc
else:
tz = zoneinfo.ZoneInfo(tzname)
tz = pds.timezone(tzname)
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, error=False)
utils.assert_tz_offset(tz)
return tz

View file

@ -1,9 +1,9 @@
import logging
# -*- coding: utf-8 -*-
import os
import time
import datetime
import calendar
import warnings
import pytz_deprecation_shim as pds
try:
import zoneinfo # pragma: no cover
@ -12,7 +12,35 @@ except ImportError:
from tzlocal import windows_tz
log = logging.getLogger("tzlocal")
class ZoneInfoNotFoundError(pds.UnknownTimeZoneError, zoneinfo.ZoneInfoNotFoundError):
"""An exception derived from both pytz and zoneinfo
This exception will be trappable both by pytz expecting clients and
zoneinfo expecting clients.
"""
def get_system_offset():
"""Get system's timezone offset using built-in library time.
For the Timezone constants (altzone, daylight, timezone, and tzname), the
value is determined by the timezone rules in effect at module load time or
the last time tzset() is called and may be incorrect for times in the past.
To keep compatibility with Windows, we're always importing time module here.
"""
localtime = calendar.timegm(time.localtime())
gmtime = calendar.timegm(time.gmtime())
offset = gmtime - localtime
# We could get the localtime and gmtime on either side of a second switch
# so we check that the difference is less than one minute, because nobody
# has that small DST differences.
if abs(offset - time.altzone) < 60:
return -time.altzone # pragma: no cover
else:
return -time.timezone # pragma: no cover
def get_tz_offset(tz):
@ -20,27 +48,19 @@ def get_tz_offset(tz):
return int(datetime.datetime.now(tz).utcoffset().total_seconds())
def assert_tz_offset(tz, error=True):
def assert_tz_offset(tz):
"""Assert that system's timezone offset equals to the timezone offset found.
If they don't match, we probably have a misconfiguration, for example, an
incorrect timezone set in /etc/timezone file in systemd distributions.
If error is True, this method will raise a ValueError, otherwise it will
emit a warning.
"""
incorrect timezone set in /etc/timezone file in systemd distributions."""
tz_offset = get_tz_offset(tz)
system_offset = calendar.timegm(time.localtime()) - calendar.timegm(time.gmtime())
# No one has timezone offsets less than a minute, so this should be close enough:
if abs(tz_offset - system_offset) > 60:
system_offset = get_system_offset()
if tz_offset != system_offset:
msg = (
"Timezone offset does not match system offset: {} != {}. "
"Please, check your config files."
).format(tz_offset, system_offset)
if error:
raise ValueError(msg)
warnings.warn(msg)
raise ValueError(msg)
def _tz_name_from_env(tzenv=None):
@ -50,8 +70,6 @@ def _tz_name_from_env(tzenv=None):
if not tzenv:
return None
log.debug(f"Found a TZ environment: {tzenv}")
if tzenv[0] == ":":
tzenv = tzenv[1:]
@ -74,9 +92,6 @@ def _tz_name_from_env(tzenv=None):
# Indeed
return parts[-1]
log.debug("TZ does not contain a time zone name")
return None
def _tz_from_env(tzenv=None):
if tzenv is None:
@ -97,16 +112,17 @@ def _tz_from_env(tzenv=None):
# Nope, not a standard timezone name, just take the filename
tzname = tzenv.split(os.sep)[-1]
with open(tzenv, "rb") as tzfile:
return zoneinfo.ZoneInfo.from_file(tzfile, key=tzname)
zone = zoneinfo.ZoneInfo.from_file(tzfile, key=tzname)
return pds.wrap_zone(zone)
# TZ must specify a zoneinfo zone.
try:
tz = zoneinfo.ZoneInfo(tzenv)
tz = pds.timezone(tzenv)
# That worked, so we return this:
return tz
except zoneinfo.ZoneInfoNotFoundError:
except pds.UnknownTimeZoneError:
# Nope, it's something like "PST4DST" etc, we can't handle that.
raise zoneinfo.ZoneInfoNotFoundError(
raise ZoneInfoNotFoundError(
"tzlocal() does not support non-zoneinfo timezones like %s. \n"
"Please use a timezone in the form of Continent/City" % tzenv
"Please use a timezone in the form of Continent/City"
) from None

View file

@ -1,24 +1,17 @@
import logging
from datetime import datetime
import pytz_deprecation_shim as pds
try:
import _winreg as winreg
except ImportError:
import winreg
try:
import zoneinfo # pragma: no cover
except ImportError:
from backports import zoneinfo # pragma: no cover
from tzlocal.windows_tz import win_tz
from tzlocal import utils
_cache_tz = None
_cache_tz_name = None
log = logging.getLogger("tzlocal")
def valuestodict(key):
"""Convert a registry key's values to a dictionary."""
@ -55,7 +48,6 @@ def _get_localzone_name():
if tzenv:
return tzenv
log.debug("Looking up time zone info from registry")
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
@ -82,13 +74,13 @@ def _get_localzone_name():
# Return what we have.
if timezone is None:
raise zoneinfo.ZoneInfoNotFoundError(tzkeyname)
raise utils.ZoneInfoNotFoundError(tzkeyname)
if keyvalues.get("DynamicDaylightTimeDisabled", 0) == 1:
# DST is disabled, so don't return the timezone name,
# instead return Etc/GMT+offset
tz = zoneinfo.ZoneInfo(timezone)
tz = pds.timezone(timezone)
has_dst, std_offset, dst_offset = _get_dst_info(tz)
if not has_dst:
# The DST is turned off in the windows configuration,
@ -96,15 +88,13 @@ def _get_localzone_name():
return timezone
if std_offset is None:
raise zoneinfo.ZoneInfoNotFoundError(
f"{tzkeyname} claims to not have a non-DST time!?"
)
raise utils.ZoneInfoNotFoundError(
f"{tzkeyname} claims to not have a non-DST time!?")
if std_offset % 3600:
# I can't convert this to an hourly offset
raise zoneinfo.ZoneInfoNotFoundError(
f"tzlocal can't support disabling DST in the {timezone} zone."
)
raise utils.ZoneInfoNotFoundError(
f"tzlocal can't support disabling DST in the {timezone} zone.")
# This has whole hours as offset, return it as Etc/GMT
return f"Etc/GMT{-std_offset//3600:+.0f}"
@ -126,13 +116,13 @@ def get_localzone():
global _cache_tz
if _cache_tz is None:
_cache_tz = zoneinfo.ZoneInfo(get_localzone_name())
_cache_tz = pds.timezone(get_localzone_name())
if not utils._tz_name_from_env():
# If the timezone does NOT come from a TZ environment variable,
# verify that it's correct. If it's from the environment,
# we accept it, this is so you can run tests with different timezones.
utils.assert_tz_offset(_cache_tz, error=False)
utils.assert_tz_offset(_cache_tz)
return _cache_tz
@ -142,6 +132,6 @@ def reload_localzone():
global _cache_tz
global _cache_tz_name
_cache_tz_name = _get_localzone_name()
_cache_tz = zoneinfo.ZoneInfo(_cache_tz_name)
utils.assert_tz_offset(_cache_tz, error=False)
_cache_tz = pds.timezone(_cache_tz_name)
utils.assert_tz_offset(_cache_tz)
return _cache_tz

File diff suppressed because it is too large Load diff