Bump apscheduler from 3.10.1 to 3.10.4 (#2133)

* Bump apscheduler from 3.10.1 to 3.10.4

Bumps [apscheduler](https://github.com/agronholm/apscheduler) from 3.10.1 to 3.10.4.
- [Changelog](https://github.com/agronholm/apscheduler/blob/3.10.4/docs/versionhistory.rst)
- [Commits](https://github.com/agronholm/apscheduler/compare/3.10.1...3.10.4)

---
updated-dependencies:
- dependency-name: apscheduler
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update apscheduler==3.10.4

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>

[skip ci]
This commit is contained in:
dependabot[bot] 2023-08-24 12:10:08 -07:00 committed by GitHub
parent 3debeada2a
commit 2c42150799
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 855 additions and 825 deletions

View file

@ -1,10 +1,15 @@
from pkg_resources import get_distribution, DistributionNotFound import sys
if sys.version_info >= (3, 8):
import importlib.metadata as importlib_metadata
else:
import importlib_metadata
try: try:
release = get_distribution('APScheduler').version.split('-')[0] release = importlib_metadata.version('APScheduler').split('-')[0]
except DistributionNotFound: except importlib_metadata.PackageNotFoundError:
release = '3.5.0' release = '3.5.0'
version_info = tuple(int(x) if x.isdigit() else x for x in release.split('.')) version_info = tuple(int(x) if x.isdigit() else x for x in release.split('.'))
version = __version__ = '.'.join(str(x) for x in version_info[:3]) version = __version__ = '.'.join(str(x) for x in version_info[:3])
del get_distribution, DistributionNotFound del sys, importlib_metadata

View file

@ -7,7 +7,6 @@ from logging import getLogger
import warnings import warnings
import sys import sys
from pkg_resources import iter_entry_points
from tzlocal import get_localzone from tzlocal import get_localzone
import six import six
@ -31,6 +30,11 @@ try:
except ImportError: except ImportError:
from collections import MutableMapping from collections import MutableMapping
try:
from importlib.metadata import entry_points
except ModuleNotFoundError:
from importlib_metadata import entry_points
#: constant indicating a scheduler's stopped state #: constant indicating a scheduler's stopped state
STATE_STOPPED = 0 STATE_STOPPED = 0
#: constant indicating a scheduler's running state (started and processing jobs) #: constant indicating a scheduler's running state (started and processing jobs)
@ -62,12 +66,18 @@ class BaseScheduler(six.with_metaclass(ABCMeta)):
.. seealso:: :ref:`scheduler-config` .. seealso:: :ref:`scheduler-config`
""" """
# The `group=...` API is only available in the backport, used in <=3.7, and in std>=3.10.
if (3, 8) <= sys.version_info < (3, 10):
_trigger_plugins = {ep.name: ep for ep in entry_points()['apscheduler.triggers']}
_executor_plugins = {ep.name: ep for ep in entry_points()['apscheduler.executors']}
_jobstore_plugins = {ep.name: ep for ep in entry_points()['apscheduler.jobstores']}
else:
_trigger_plugins = {ep.name: ep for ep in entry_points(group='apscheduler.triggers')}
_executor_plugins = {ep.name: ep for ep in entry_points(group='apscheduler.executors')}
_jobstore_plugins = {ep.name: ep for ep in entry_points(group='apscheduler.jobstores')}
_trigger_plugins = dict((ep.name, ep) for ep in iter_entry_points('apscheduler.triggers'))
_trigger_classes = {} _trigger_classes = {}
_executor_plugins = dict((ep.name, ep) for ep in iter_entry_points('apscheduler.executors'))
_executor_classes = {} _executor_classes = {}
_jobstore_plugins = dict((ep.name, ep) for ep in iter_entry_points('apscheduler.jobstores'))
_jobstore_classes = {} _jobstore_classes = {}
# #
@ -1019,6 +1029,7 @@ class BaseScheduler(six.with_metaclass(ABCMeta)):
wait_seconds = None wait_seconds = None
self._logger.debug('No jobs; waiting until a job is added') self._logger.debug('No jobs; waiting until a job is added')
else: else:
now = datetime.now(self.timezone)
wait_seconds = min(max(timedelta_seconds(next_wakeup_time - now), 0), TIMEOUT_MAX) wait_seconds = min(max(timedelta_seconds(next_wakeup_time - now), 0), TIMEOUT_MAX)
self._logger.debug('Next wakeup is due at %s (in %f seconds)', next_wakeup_time, self._logger.debug('Next wakeup is due at %s (in %f seconds)', next_wakeup_time,
wait_seconds) wait_seconds)

View file

@ -1,24 +1,22 @@
from __future__ import absolute_import from __future__ import absolute_import
from importlib import import_module
from itertools import product
from apscheduler.schedulers.base import BaseScheduler from apscheduler.schedulers.base import BaseScheduler
try: for version, pkgname in product(range(6, 1, -1), ("PySide", "PyQt")):
from PyQt5.QtCore import QObject, QTimer
except (ImportError, RuntimeError): # pragma: nocover
try: try:
from PyQt4.QtCore import QObject, QTimer qtcore = import_module(pkgname + str(version) + ".QtCore")
except ImportError: except ImportError:
try: pass
from PySide6.QtCore import QObject, QTimer # noqa else:
except ImportError: QTimer = qtcore.QTimer
try: break
from PySide2.QtCore import QObject, QTimer # noqa else:
except ImportError: raise ImportError(
try: "QtScheduler requires either PySide/PyQt (v6 to v2) installed"
from PySide.QtCore import QObject, QTimer # noqa )
except ImportError:
raise ImportError('QtScheduler requires either PyQt5, PyQt4, PySide6, PySide2 '
'or PySide installed')
class QtScheduler(BaseScheduler): class QtScheduler(BaseScheduler):

View file

@ -6,7 +6,7 @@ from asyncio import iscoroutinefunction
from datetime import date, datetime, time, timedelta, tzinfo from datetime import date, datetime, time, timedelta, tzinfo
from calendar import timegm from calendar import timegm
from functools import partial from functools import partial
from inspect import isclass, ismethod from inspect import isbuiltin, isclass, isfunction, ismethod
import re import re
import sys import sys
@ -214,28 +214,15 @@ def get_callable_name(func):
:rtype: str :rtype: str
""" """
# the easy case (on Python 3.3+) if ismethod(func):
if hasattr(func, '__qualname__'): self = func.__self__
cls = self if isclass(self) else type(self)
return f"{cls.__qualname__}.{func.__name__}"
elif isclass(func) or isfunction(func) or isbuiltin(func):
return func.__qualname__ return func.__qualname__
elif hasattr(func, '__call__') and callable(func.__call__):
# class methods, bound and unbound methods
f_self = getattr(func, '__self__', None) or getattr(func, 'im_self', None)
if f_self and hasattr(func, '__name__'):
f_class = f_self if isclass(f_self) else f_self.__class__
else:
f_class = getattr(func, 'im_class', None)
if f_class and hasattr(func, '__name__'):
return '%s.%s' % (f_class.__name__, func.__name__)
# class or class instance
if hasattr(func, '__call__'):
# class
if hasattr(func, '__name__'):
return func.__name__
# instance of a class with a __call__ method # instance of a class with a __call__ method
return func.__class__.__name__ return type(func).__qualname__
raise TypeError('Unable to determine a name for %r -- maybe it is not a callable?' % func) raise TypeError('Unable to determine a name for %r -- maybe it is not a callable?' % func)
@ -260,16 +247,10 @@ def obj_to_ref(obj):
raise ValueError('Cannot create a reference to a nested function') raise ValueError('Cannot create a reference to a nested function')
if ismethod(obj): if ismethod(obj):
if hasattr(obj, 'im_self') and obj.im_self: module = obj.__self__.__module__
# bound method
module = obj.im_self.__module__
elif hasattr(obj, 'im_class') and obj.im_class:
# unbound method
module = obj.im_class.__module__
else:
module = obj.__module__
else: else:
module = obj.__module__ module = obj.__module__
return '%s:%s' % (module, name) return '%s:%s' % (module, name)

View file

@ -9,5 +9,12 @@ if sys.platform == "win32":
else: else:
from tzlocal.unix import get_localzone, get_localzone_name, reload_localzone 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"]
__all__ = [
"get_localzone",
"get_localzone_name",
"reload_localzone",
"assert_tz_offset",
]

View file

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

View file

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- import logging
import os import os
import time import time
import datetime import datetime
import calendar import calendar
import pytz_deprecation_shim as pds import warnings
try: try:
import zoneinfo # pragma: no cover import zoneinfo # pragma: no cover
@ -12,35 +12,7 @@ except ImportError:
from tzlocal import windows_tz 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): def get_tz_offset(tz):
@ -48,19 +20,27 @@ def get_tz_offset(tz):
return int(datetime.datetime.now(tz).utcoffset().total_seconds()) return int(datetime.datetime.now(tz).utcoffset().total_seconds())
def assert_tz_offset(tz): def assert_tz_offset(tz, error=True):
"""Assert that system's timezone offset equals to the timezone offset found. """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 If they don't match, we probably have a misconfiguration, for example, an
incorrect timezone set in /etc/timezone file in systemd distributions.""" 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.
"""
tz_offset = get_tz_offset(tz) tz_offset = get_tz_offset(tz)
system_offset = get_system_offset() system_offset = calendar.timegm(time.localtime()) - calendar.timegm(time.gmtime())
if tz_offset != system_offset: # No one has timezone offsets less than a minute, so this should be close enough:
if abs(tz_offset - system_offset) > 60:
msg = ( msg = (
"Timezone offset does not match system offset: {} != {}. " "Timezone offset does not match system offset: {} != {}. "
"Please, check your config files." "Please, check your config files."
).format(tz_offset, system_offset) ).format(tz_offset, system_offset)
raise ValueError(msg) if error:
raise ValueError(msg)
warnings.warn(msg)
def _tz_name_from_env(tzenv=None): def _tz_name_from_env(tzenv=None):
@ -70,6 +50,8 @@ def _tz_name_from_env(tzenv=None):
if not tzenv: if not tzenv:
return None return None
log.debug(f"Found a TZ environment: {tzenv}")
if tzenv[0] == ":": if tzenv[0] == ":":
tzenv = tzenv[1:] tzenv = tzenv[1:]
@ -92,6 +74,9 @@ def _tz_name_from_env(tzenv=None):
# Indeed # Indeed
return parts[-1] return parts[-1]
log.debug("TZ does not contain a time zone name")
return None
def _tz_from_env(tzenv=None): def _tz_from_env(tzenv=None):
if tzenv is None: if tzenv is None:
@ -112,17 +97,16 @@ def _tz_from_env(tzenv=None):
# Nope, not a standard timezone name, just take the filename # Nope, not a standard timezone name, just take the filename
tzname = tzenv.split(os.sep)[-1] tzname = tzenv.split(os.sep)[-1]
with open(tzenv, "rb") as tzfile: with open(tzenv, "rb") as tzfile:
zone = zoneinfo.ZoneInfo.from_file(tzfile, key=tzname) return zoneinfo.ZoneInfo.from_file(tzfile, key=tzname)
return pds.wrap_zone(zone)
# TZ must specify a zoneinfo zone. # TZ must specify a zoneinfo zone.
try: try:
tz = pds.timezone(tzenv) tz = zoneinfo.ZoneInfo(tzenv)
# That worked, so we return this: # That worked, so we return this:
return tz return tz
except pds.UnknownTimeZoneError: except zoneinfo.ZoneInfoNotFoundError:
# Nope, it's something like "PST4DST" etc, we can't handle that. # Nope, it's something like "PST4DST" etc, we can't handle that.
raise ZoneInfoNotFoundError( raise zoneinfo.ZoneInfoNotFoundError(
"tzlocal() does not support non-zoneinfo timezones like %s. \n" "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" % tzenv
) from None ) from None

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
apscheduler==3.10.1 apscheduler==3.10.4
importlib-metadata==6.8.0 importlib-metadata==6.8.0
importlib-resources==6.0.1 importlib-resources==6.0.1
pyinstaller==5.13.0 pyinstaller==5.13.0

View file

@ -1,5 +1,5 @@
appdirs==1.4.4 appdirs==1.4.4
apscheduler==3.10.1 apscheduler==3.10.4
arrow==1.2.3 arrow==1.2.3
backports.csv==1.0.7 backports.csv==1.0.7
backports.functools-lru-cache==1.6.6 backports.functools-lru-cache==1.6.6