Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-tzlocal for openSUSE:Factory checked in at 2026-07-07 21:00:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-tzlocal (Old) and /work/SRC/openSUSE:Factory/.python-tzlocal.new.1982 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-tzlocal" Tue Jul 7 21:00:03 2026 rev:20 rq:1363876 version:5.4.4 Changes: -------- --- /work/SRC/openSUSE:Factory/python-tzlocal/python-tzlocal.changes 2026-02-06 19:07:18.580429822 +0100 +++ /work/SRC/openSUSE:Factory/.python-tzlocal.new.1982/python-tzlocal.changes 2026-07-07 21:00:27.832641086 +0200 @@ -1,0 +2,12 @@ +Sun Jul 5 14:59:36 UTC 2026 - Dirk Müller <[email protected]> + +- update to 5.4.4: + * Improved handling if you have a syntax error in /etc/clock. + * Moved the tests back, removed the ones that check for + symlinks. + * Open files with Zone names as ascii. + * Moved tests under `tzlocal/tests` and include them in + distributions. + * Dropped support for Python 3.9 and added support for 3.14. + +------------------------------------------------------------------- Old: ---- 5.3.1.tar.gz New: ---- 5.4.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-tzlocal.spec ++++++ --- /var/tmp/diff_new_pack.fELQMu/_old 2026-07-07 21:00:28.844675851 +0200 +++ /var/tmp/diff_new_pack.fELQMu/_new 2026-07-07 21:00:28.848675988 +0200 @@ -19,7 +19,7 @@ %define modname tzlocal %{?sle15_python_module_pythons} Name: python-%{modname} -Version: 5.3.1 +Version: 5.4.4 Release: 0 Summary: Timezone information (tzinfo) object for the local timezone License: MIT ++++++ 5.3.1.tar.gz -> 5.4.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/.github/workflows/lint.yml new/tzlocal-5.4.4/.github/workflows/lint.yml --- old/tzlocal-5.3.1/.github/workflows/lint.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/tzlocal-5.4.4/.github/workflows/lint.yml 2026-06-29 10:03:29.000000000 +0200 @@ -0,0 +1,32 @@ +name: Run the checks + +on: + push: + branches: [master] + pull_request: + +jobs: + test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + python-version: ["3.14"] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v6 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + - uses: actions/cache@v5 + with: + path: ~/.cache/pip + key: pip-test-${{ matrix.python-version }}-${{ matrix.os }} + - name: Install dependencies + run: pip install -e .[testing] + - name: Check with ruff + run: ruff check tzlocal tests + - name: Check with pyroma + run: pyroma -d . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/.github/workflows/test.yml new/tzlocal-5.4.4/.github/workflows/test.yml --- old/tzlocal-5.3.1/.github/workflows/test.yml 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/.github/workflows/test.yml 2026-06-29 10:03:29.000000000 +0200 @@ -11,33 +11,25 @@ fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.9", "3.13", "3.14-dev", "pypy3.10"] + python-version: ["3.10", "3.14", "pypy3.11"] exclude: - os: macos-latest - python-version: 3.9 - - os: macos-latest - python-version: 3.13 - - os: macos-latest - python-version: pypy3 - - os: windows-latest - python-version: 3.9 - - os: windows-latest - python-version: 3.13 + python-version: "pypy3.11" - os: windows-latest - python-version: pypy3 + python-version: "pypy3.11" runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - - uses: actions/cache@v3 + - uses: actions/cache@v5 with: path: ~/.cache/pip key: pip-test-${{ matrix.python-version }}-${{ matrix.os }} - name: Install dependencies - run: pip install .[devenv] + run: pip install -e .[testing] - name: Test with pytest run: pytest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/.gitignore new/tzlocal-5.4.4/.gitignore --- old/tzlocal-5.3.1/.gitignore 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/.gitignore 2026-06-29 10:03:29.000000000 +0200 @@ -4,3 +4,5 @@ *.egg-info *.egg .tox +.coverage +dist diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/CHANGES.txt new/tzlocal-5.4.4/CHANGES.txt --- old/tzlocal-5.3.1/CHANGES.txt 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/CHANGES.txt 2026-06-29 10:03:29.000000000 +0200 @@ -1,6 +1,38 @@ Changes ======= +5.4.4 (2026-06-29) +------------------ + +- Improved handling if you have a syntax error in /etc/clock. + + +5.4.3 (2026-06-17) +------------------ + +- Moved the tests back, removed the ones that check for symlinks. + See issue #146 + +5.4.2 (2026-06-16) +------------------ + +- [Yanked for distribution issues] + +5.4.1 (2026-06-16) +------------------ + +- [Yanked for distribution issues] + +5.4 (2026-06-15) +---------------- + +- Open files with Zone names as ascii. + +- Moved tests under `tzlocal/tests` and include them in distributions. + +- Dropped support for Python 3.9 and added support for 3.14. + + 5.3.1 (2025-03-05) ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/MANIFEST.in new/tzlocal-5.4.4/MANIFEST.in --- old/tzlocal-5.3.1/MANIFEST.in 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/MANIFEST.in 2026-06-29 10:03:29.000000000 +0200 @@ -3,5 +3,6 @@ include *.txt include tzlocal/py.typed recursive-include tests/test_data * -include tests/*.py +recursive-include tzlocal *.py exclude Makefile +exclude *.yaml \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/Makefile new/tzlocal-5.4.4/Makefile --- old/tzlocal-5.3.1/Makefile 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/Makefile 2026-06-29 10:03:29.000000000 +0200 @@ -9,14 +9,13 @@ ve/bin/fullrelease: virtualenv ve - $(bin_dir)/pip install -e .[devenv] + $(bin_dir)/pip install -e .[testing,devenv] update_mapping: $(bin_dir)/python update_windows_mappings.py check: - $(bin_dir)/black tzlocal tests - $(bin_dir)/flake8 tzlocal tests + $(bin_dir)/ruff check tzlocal tests $(bin_dir)/pyroma -d . coverage: @@ -24,7 +23,7 @@ $(bin_dir)/coverage html $(bin_dir)/coverage report -test: +test: ve/bin/fullrelease $(bin_dir)/pytest release: update_mapping check diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/pyproject.toml new/tzlocal-5.4.4/pyproject.toml --- old/tzlocal-5.3.1/pyproject.toml 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/pyproject.toml 2026-06-29 10:03:29.000000000 +0200 @@ -6,24 +6,23 @@ name = "tzlocal" description = "tzinfo object for the local timezone" readme = "README.rst" -version = "5.3.1" +version = "5.4.4" authors = [{name = "Lennart Regebro", email = "[email protected]"}] -license = {text = "MIT"} +license = "MIT" keywords = ["timezone"] classifiers = [ - "Development Status :: 5 - Production/Stable", - "License :: OSI Approved :: MIT License", + "Development Status :: 6 - Mature", "Operating System :: Microsoft :: Windows", "Operating System :: Unix", "Operating System :: MacOS :: MacOS X", "Typing :: Typed", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] -requires-python = ">= 3.9" +requires-python = ">= 3.10" dependencies = [ "tzdata; platform_system == 'Windows'", ] @@ -34,16 +33,31 @@ "Issue tracker" = "https://github.com/regebro/tzlocal/issues" [project.optional-dependencies] -devenv = [ +testing = [ "pytest >= 4.3", "pytest-mock >= 3.3", "pytest-cov", "check_manifest", + "pyroma", + "ruff", +] +devenv = [ "zest.releaser", ] +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +include = ["tzlocal"] + +[tool.setuptools.package-data] +"tzlocal.tests" = ["test_data/**/*"] + [tool.ruff] line-length = 120 + +[lint] select = [ "E", "F", "W", # default flake-8 "I", # isort diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/tests/test_data/broken/etc/conf.d/clock new/tzlocal-5.4.4/tests/test_data/broken/etc/conf.d/clock --- old/tzlocal-5.3.1/tests/test_data/broken/etc/conf.d/clock 1970-01-01 01:00:00.000000000 +0100 +++ new/tzlocal-5.4.4/tests/test_data/broken/etc/conf.d/clock 2026-06-29 10:03:29.000000000 +0200 @@ -0,0 +1 @@ +TIMEZONE = "Africa/Harare diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/tests/test_tzlocal.py new/tzlocal-5.4.4/tests/test_tzlocal.py --- old/tzlocal-5.3.1/tests/test_tzlocal.py 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/tests/test_tzlocal.py 2026-06-29 10:03:29.000000000 +0200 @@ -1,19 +1,16 @@ +import logging import os -import platform import sys -from datetime import datetime, timezone +from datetime import datetime from pathlib import Path from unittest.mock import MagicMock, Mock +from zoneinfo import ZoneInfo, ZoneInfoNotFoundError import pytest import tzlocal.unix import tzlocal.utils -from zoneinfo import ZoneInfo, ZoneInfoNotFoundError - -import logging - logging.basicConfig(level=logging.DEBUG) @@ -87,16 +84,6 @@ assert str(tz) == "Africa/Harare" [email protected]( - platform.system() == "Windows", reason="Symbolic links are not available on Windows" -) -def test_symlink_localtime(): - # A ZONE setting in the target path of a symbolic linked localtime, f ex systemd distributions - - tz = tzlocal.unix._get_localzone(_root=tz_path("symlink_localtime")) - assert str(tz) == "Africa/Harare" - - def test_vardbzoneinfo_setting(): # A ZONE setting in /etc/conf.d/clock, f ex Gentoo @@ -172,9 +159,7 @@ # catch syntax errors, etc. mocker.patch("tzlocal.utils.assert_tz_offset") winreg = MagicMock() - winreg.EnumValue.configure_mock( - return_value=("TimeZoneKeyName", "Belarus Standard Time") - ) + winreg.EnumValue.configure_mock(return_value=("TimeZoneKeyName", "Belarus Standard Time")) sys.modules["winreg"] = winreg import tzlocal.win32 @@ -185,15 +170,11 @@ tz = tzlocal.win32.reload_localzone() assert str(tz) == "Europe/Minsk" - winreg.EnumValue.configure_mock( - return_value=("TimeZoneKeyName", "Not a real timezone") - ) + winreg.EnumValue.configure_mock(return_value=("TimeZoneKeyName", "Not a real timezone")) pytest.raises(ZoneInfoNotFoundError, tzlocal.win32._get_localzone_name) # Old XP style reginfo should fail - winreg.EnumValue.configure_mock( - return_value=("TimeZoneKeyName", "Belarus Standard Time") - ) + winreg.EnumValue.configure_mock(return_value=("TimeZoneKeyName", "Belarus Standard Time")) tzlocal.win32.valuestodict = Mock( return_value={ "StandardName": "Mocked Standard Time", @@ -274,9 +255,6 @@ assert str(tz) == "Africa/Johannesburg" [email protected]( - platform.system() == "Windows", reason="Symbolic links are not available on Windows" -) def test_conflicting(): with pytest.raises(ZoneInfoNotFoundError) as excinfo: tzlocal.unix._get_localzone(_root=tz_path("conflicting")) @@ -285,16 +263,7 @@ assert "America/New_York" in message assert "Europe/Warsaw" in message assert "Africa/Johannesburg" in message - assert "localtime is a symlink to: Africa/Harare" in message - - [email protected]( - platform.system() == "Windows", reason="Symbolic links are not available on Windows" -) -def test_noconflict(): - tz = tzlocal.unix._get_localzone(_root=tz_path("noconflict")) - assert str(tz) == "Etc/UTC" - + def test_zoneinfo_compatibility(): os.environ["TZ"] = "Africa/Harare" @@ -325,3 +294,13 @@ def test_ubuntu_docker_bug(): tz = tzlocal.unix._get_localzone(_root=tz_path("ubuntu_docker_bug")) assert str(tz) == "UTC" + + +def test_broken(): + # Various broken configs, that should be ignored, and we should fall back to UTC. + # The first warning is about not finding any timezone configuration, the second + # is about a syntax error in the config file. + with pytest.warns(UserWarning, match="Can not find any timezone configuration"): + with pytest.warns(UserWarning, match="Syntax error in"): + tz = tzlocal.unix._get_localzone(_root=tz_path("broken")) + assert "UTC" in tz.key diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/tzlocal/__init__.py new/tzlocal-5.4.4/tzlocal/__init__.py --- old/tzlocal-5.3.1/tzlocal/__init__.py 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/tzlocal/__init__.py 2026-06-29 10:03:29.000000000 +0200 @@ -1,11 +1,7 @@ import sys if sys.platform == "win32": - from tzlocal.win32 import ( - get_localzone, - get_localzone_name, - reload_localzone, - ) + from tzlocal.win32 import get_localzone, get_localzone_name, reload_localzone else: from tzlocal.unix import get_localzone, get_localzone_name, reload_localzone diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/tzlocal/unix.py new/tzlocal-5.4.4/tzlocal/unix.py --- old/tzlocal-5.3.1/tzlocal/unix.py 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/tzlocal/unix.py 2026-06-29 10:03:29.000000000 +0200 @@ -1,14 +1,12 @@ import logging import os import re -import sys import warnings +import zoneinfo from datetime import timezone from tzlocal import utils -import zoneinfo - _cache_tz = None _cache_tz_name = None @@ -36,11 +34,7 @@ import subprocess try: - androidtz = ( - subprocess.check_output(["getprop", "persist.sys.timezone"]) - .strip() - .decode() - ) + androidtz = subprocess.check_output(["getprop", "persist.sys.timezone"]).strip().decode() return androidtz except (OSError, subprocess.CalledProcessError): # proot environment or failed to getprop @@ -56,7 +50,7 @@ for configfile in ("etc/timezone", "var/db/zoneinfo"): tzpath = os.path.join(_root, configfile) try: - with open(tzpath) as tzfile: + with open(tzpath, encoding="ascii") as tzfile: data = tzfile.read() log.debug(f"{tzpath} found, contents:\n {data}") @@ -67,9 +61,9 @@ for etctz in etctz.splitlines(): # Get rid of host definitions and comments: if " " in etctz: - etctz, dummy = etctz.split(" ", 1) + etctz, _ = etctz.split(" ", 1) if "#" in etctz: - etctz, dummy = etctz.split("#", 1) + etctz, _ = etctz.split("#", 1) if not etctz: continue @@ -103,8 +97,13 @@ match = timezone_re.match(line) if match is not None: # Some setting existed - line = line[match.end() :] - etctz = line[: end_re.search(line).start()] + tzline = line[match.end() :] + end_match = end_re.search(tzline) + if end_match is None: + # Syntax error. Ignore this line. + warnings.warn(f"Syntax error in {tzpath}. Ignoring line: {line}") + continue + etctz = tzline[:end_match.start()] # We found a timezone found_configs[tzpath] = etctz.replace(" ", "_") @@ -141,12 +140,14 @@ unique_tzs = _get_unique_tzs(found_configs, _root) if len(unique_tzs) != 1 and "etc/timezone" in str(found_configs.keys()): - # For some reason some distros are removing support for /etc/timezone, - # which is bad, because that's the only place where the timezone is stated - # in plain text, and what's worse, they don't delete it. So we can't trust + # For some reason some distros are removing support for /etc/timezone, + # which is bad, because that's the only place where the timezone is stated + # in plain text, and what's worse, they don't delete it. So we can't trust # it now, so when we have conflicting configs, we just ignore it, with a warning. - log.warning("/etc/timezone is deprecated in some distros, and no longer reliable. " - "tzlocal is ignoring it, and you can likely delete it.") + log.warning( + "/etc/timezone is deprecated in some distros, and no longer reliable. " + "tzlocal is ignoring it, and you can likely delete it." + ) found_configs = {k: v for k, v in found_configs.items() if "etc/timezone" not in k} unique_tzs = _get_unique_tzs(found_configs, _root) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/tzlocal/win32.py new/tzlocal-5.4.4/tzlocal/win32.py --- old/tzlocal-5.3.1/tzlocal/win32.py 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/tzlocal/win32.py 2026-06-29 10:03:29.000000000 +0200 @@ -93,18 +93,14 @@ return timezone if std_offset is None: - raise zoneinfo.ZoneInfoNotFoundError( - f"{tzkeyname} claims to not have a non-DST time!?" - ) + raise zoneinfo.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 zoneinfo.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}" + return f"Etc/GMT{-std_offset // 3600:+.0f}" return timezone diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tzlocal-5.3.1/update_windows_mappings.py new/tzlocal-5.4.4/update_windows_mappings.py --- old/tzlocal-5.3.1/update_windows_mappings.py 2025-03-05 22:17:33.000000000 +0100 +++ new/tzlocal-5.4.4/update_windows_mappings.py 2026-06-29 10:03:29.000000000 +0200 @@ -27,7 +27,7 @@ """Fetches the list of old tz names and returns a mapping""" url = urlparse(ZONEINFO_URL) - log.info("Connecting to %s" % url.netloc) + log.info(f"Connecting to {url.netloc}") ftp = ftplib.FTP(url.netloc) ftp.login() gzfile = BytesIO()
