From 42cdc5ca74af850a225f32fc8478e02414e1c181 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek Date: Thu, 6 Nov 2025 18:28:59 +0900 Subject: [PATCH 01/14] chore: update pylint --- requirements_ci.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements_ci.txt b/requirements_ci.txt index 8d9b526..7e8f43a 100644 --- a/requirements_ci.txt +++ b/requirements_ci.txt @@ -4,6 +4,7 @@ coverage ~= 7.2 flake518 ~= 1.6 mypy ~= 1.5 pydocstyle ~= 6.3 -pylint ~= 3.1 +pylint ~= 3.3; python_version < '3.10' +pylint ~= 4.0; python_version >= '3.10' twine ~= 6.1 types-setuptools >= 67.4 From 801376db9fec5770ff595f1a965cc7327a534b68 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 13:33:00 +0900 Subject: [PATCH 02/14] chore: update copyright year --- NOTICE | 2 +- version_query/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NOTICE b/NOTICE index 11992d3..2f6f002 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ version-query -Copyright (c) 2017-2025 Mateusz Bysiek https://mbdevpl.github.io/ +Copyright (c) 2017-2026 Mateusz Bysiek https://mbdevpl.github.io/ Copyright (c) 2020 John Vandenberg https://github.com/jayvdb Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/version_query/main.py b/version_query/main.py index 5084d05..ab9907a 100644 --- a/version_query/main.py +++ b/version_query/main.py @@ -20,7 +20,7 @@ def main(args=None, namespace=None) -> None: description='''Tool for querying current versions of Python packages. Use LOGGING_LEVEL environment variable to adjust logging level.''', epilog=make_copyright_notice( - 2017, 2025, author='the contributors', url='https://github.com/mbdevpl/version-query'), + 2017, 2026, author='the contributors', url='https://github.com/mbdevpl/version-query'), formatter_class=argparse.ArgumentDefaultsHelpFormatter) add_version_option(parser, VERSION) From b5260ed0d804650af54ad5365f16553d851681a6 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 13:34:29 +0900 Subject: [PATCH 03/14] chore: remove old macos --- .github/workflows/python.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index dde4172..d764930 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -22,15 +22,6 @@ jobs: python-version: '3.10' - os: macos-latest python-version: 'pypy3.10' - include: - - os: macos-13 - python-version: '3.9' - - os: macos-13 - python-version: 'pypy3.9' - - os: macos-13 - python-version: '3.10' - - os: macos-13 - python-version: 'pypy3.10' steps: - uses: actions/checkout@v5 with: From 7891af3401d060a2a5c9753af557ce0fd978ce57 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 13:46:38 +0900 Subject: [PATCH 04/14] chore: remove EOL python 3.9 --- .github/workflows/python.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index d764930..76c1c4a 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -12,12 +12,8 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.9', 'pypy3.9', '3.10', 'pypy3.10', '3.11', '3.12', '3.13'] + python-version: ['3.10', 'pypy3.10', '3.11', '3.12', '3.13'] exclude: - - os: macos-latest - python-version: '3.9' - - os: macos-latest - python-version: 'pypy3.9' - os: macos-latest python-version: '3.10' - os: macos-latest From d8a677e96b127af8ee24e52987754c605cfcf350 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 13:54:04 +0900 Subject: [PATCH 05/14] fix: don't use pkg_resources --- test/test_version.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/test/test_version.py b/test/test_version.py index cd08309..9aaa1b9 100644 --- a/test/test_version.py +++ b/test/test_version.py @@ -4,7 +4,6 @@ import unittest import packaging.version -import pkg_resources import semver from version_query.version import VersionComponent, Version @@ -23,13 +22,12 @@ def test_from_str(self): for version_str, (args, kwargs) in STR_CASES.items(): version_tuple = case_to_version_tuple(args, kwargs) with self.subTest(version_str=version_str, version_tuple=version_tuple): - py_version = \ - pkg_resources.parse_version(version_str) + packaging.version.parse(version_str) _LOG.debug('packaging parsed version string %s into %s: %s', repr(version_str), type(py_version), py_version) - # self.assertIsInstance( - # py_version, packaging.version.Version, msg=(type(py_version), py_version)) + self.assertIsInstance( + py_version, packaging.version.Version, msg=(type(py_version), py_version)) try: sem_version = semver.VersionInfo.parse(version_str) @@ -38,8 +36,8 @@ def test_from_str(self): else: _LOG.debug('semver parsed version string %s into %s: %s', repr(version_str), type(sem_version), sem_version) - # self.assertIsInstance( - # sem_version, semver.VersionInfo, msg=(type(sem_version), sem_version)) + self.assertIsInstance( + sem_version, semver.VersionInfo, msg=(type(sem_version), sem_version)) self.assertEqual(Version.from_str(version_str).to_tuple(), version_tuple) @@ -59,7 +57,7 @@ def test_from_py_version(self): py_version = packaging.version.Version(version_str) self.assertEqual(Version.from_py_version(py_version).to_tuple(), version_tuple, py_version) - py_version_setuptools = pkg_resources.parse_version(version_str) + py_version_setuptools = packaging.version.parse(version_str) self.assertEqual(Version.from_py_version(py_version_setuptools).to_tuple(), version_tuple, py_version_setuptools) @@ -71,7 +69,6 @@ def test_to_py_version(self): py_version = packaging.version.Version(version_str) self.assertEqual(version.to_py_version(), py_version, msg=(version.to_py_version(), py_version)) - # py_version_setuptools = pkg_resources.parse_version(version_str) def test_from_sem_version(self): for version_str, (args, kwargs) in COMPATIBLE_STR_CASES.items(): From be653df5741502bfac7f725c95094dd344989342 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 15:08:21 +0900 Subject: [PATCH 06/14] test: by default don't run tests which break test logging setup --- test/test_cli.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/test_cli.py b/test/test_cli.py index a9e8527..2e1b8ae 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -3,6 +3,7 @@ import contextlib import io import logging +import os import runpy import sys import unittest @@ -42,6 +43,9 @@ class Tests(unittest.TestCase): def test_not_as_main(self): # pylint: disable = no-self-use run_module('version_query', run_name='__not_main__') + @unittest.skipUnless( + os.environ.get('TEST_CLI') or os.environ.get('CI'), + 'skipping CLI test which affects logging') def test_help(self): sio = io.StringIO() with contextlib.redirect_stderr(sio), preserve_logger_level('version_query'), \ @@ -49,6 +53,9 @@ def test_help(self): run_module('version_query') _LOG.info('%s', sio.getvalue()) + @unittest.skipUnless( + os.environ.get('TEST_CLI') or os.environ.get('CI'), + 'skipping CLI test which affects logging') def test_bad_usage(self): sio = io.StringIO() with contextlib.redirect_stderr(sio), preserve_logger_level('version_query'), \ @@ -56,6 +63,9 @@ def test_bad_usage(self): run_module('version_query', '-p', '-i', '.') _LOG.info('%s', sio.getvalue()) + @unittest.skipUnless( + os.environ.get('TEST_CLI') or os.environ.get('CI'), + 'skipping CLI test which affects logging') def test_here(self): sio = io.StringIO() with temporarily_set_logger_level('version_query', logging.ERROR), \ @@ -64,6 +74,9 @@ def test_here(self): self.assertEqual(sio.getvalue().rstrip(), query_caller().to_str()) self.assertEqual(sio.getvalue().rstrip(), query_version_str()) + @unittest.skipUnless( + os.environ.get('TEST_CLI') or os.environ.get('CI'), + 'skipping CLI test which affects logging') def test_increment_here(self): sio = io.StringIO() with temporarily_set_logger_level('version_query', logging.ERROR), \ @@ -72,6 +85,9 @@ def test_increment_here(self): self.assertEqual(sio.getvalue().rstrip(), query_caller().increment(VersionComponent.Patch).to_str()) + @unittest.skipUnless( + os.environ.get('TEST_CLI') or os.environ.get('CI'), + 'skipping CLI test which affects logging') def test_predict_here(self): sio = io.StringIO() with temporarily_set_logger_level('version_query', logging.ERROR), \ From 72a2eb169d28b385608b4fa6b2313e4bdc95d2ed Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 15:09:01 +0900 Subject: [PATCH 07/14] test: decrease test verbosity --- test/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/__init__.py b/test/__init__.py index e2a3ef0..e7135ae 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -12,3 +12,6 @@ class TestsLogging(Logging): TestsLogging.configure() +logging.getLogger('version_query.git_query').setLevel(logging.INFO) +logging.getLogger('version_query.parser').setLevel(logging.INFO) +logging.getLogger('version_query.version').setLevel(logging.INFO) From 110c2997bbc853928fced9f90067c642f9e2b5f1 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 15:16:04 +0900 Subject: [PATCH 08/14] test: don't run long tests by default --- test/test_git.py | 3 +++ test/test_query.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/test/test_git.py b/test/test_git.py index 0b6ec40..543958e 100644 --- a/test/test_git.py +++ b/test/test_git.py @@ -2,6 +2,7 @@ import itertools import logging +import os import platform import unittest @@ -79,6 +80,8 @@ def test_nonversion_tags(self): version.local = (f'git{self.repo_head_hexsha}',) self.assertEqual(version, upcoming_version) + @unittest.skipUnless( + os.environ.get('TEST_LONG', False) or os.environ.get('CI'), 'skipping long test') def test_too_long_no_tag(self): self.git_commit_new_file() self.repo.create_tag('v4.0.0') diff --git a/test/test_query.py b/test/test_query.py index c471c38..5bae762 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -60,8 +60,11 @@ def _query_test_case(self, paths, query_function): else: _LOG.debug('%s: %s', path, version) + @unittest.skipUnless( + os.environ.get('TEST_LONG', False) or os.environ.get('CI'), 'skipping long test') def test_query_git_repo(self): self._check_examples_count('git repo', GIT_REPO_EXAMPLES) + _LOG.debug('testing query_git_repo() on %i repositories', len(GIT_REPO_EXAMPLES)) self._query_test_case(GIT_REPO_EXAMPLES, query_git_repo) def test_predict_caller_bad(self): @@ -81,7 +84,10 @@ def test_predict_caller_bad(self): _LOG.warning('removed %s from sys.path', project_path_str) project_file_path.unlink() + @unittest.skipUnless( + os.environ.get('TEST_LONG', False) or os.environ.get('CI'), 'skipping long test') def test_predict_git_repo(self): + _LOG.debug('testing predict_git_repo() on %i repositories', len(GIT_REPO_EXAMPLES)) self._query_test_case(GIT_REPO_EXAMPLES, predict_git_repo) @unittest.skipIf(not METADATA_JSON_EXAMPLE_PATHS, 'no "metadata.json" files found') From e8a14805ce1cf756b418a7c78ecdbd88835600e3 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 15:22:15 +0900 Subject: [PATCH 09/14] chore: housekeeping --- test/test_cli.py | 10 +++++----- test/test_git.py | 2 +- test/test_query.py | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/test_cli.py b/test/test_cli.py index 2e1b8ae..54df6fc 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -45,7 +45,7 @@ def test_not_as_main(self): # pylint: disable = no-self-use @unittest.skipUnless( os.environ.get('TEST_CLI') or os.environ.get('CI'), - 'skipping CLI test which affects logging') + 'skipping CLI test which breaks test logging') def test_help(self): sio = io.StringIO() with contextlib.redirect_stderr(sio), preserve_logger_level('version_query'), \ @@ -55,7 +55,7 @@ def test_help(self): @unittest.skipUnless( os.environ.get('TEST_CLI') or os.environ.get('CI'), - 'skipping CLI test which affects logging') + 'skipping CLI test which breaks test logging') def test_bad_usage(self): sio = io.StringIO() with contextlib.redirect_stderr(sio), preserve_logger_level('version_query'), \ @@ -65,7 +65,7 @@ def test_bad_usage(self): @unittest.skipUnless( os.environ.get('TEST_CLI') or os.environ.get('CI'), - 'skipping CLI test which affects logging') + 'skipping CLI test which breaks test logging') def test_here(self): sio = io.StringIO() with temporarily_set_logger_level('version_query', logging.ERROR), \ @@ -76,7 +76,7 @@ def test_here(self): @unittest.skipUnless( os.environ.get('TEST_CLI') or os.environ.get('CI'), - 'skipping CLI test which affects logging') + 'skipping CLI test which breaks test logging') def test_increment_here(self): sio = io.StringIO() with temporarily_set_logger_level('version_query', logging.ERROR), \ @@ -87,7 +87,7 @@ def test_increment_here(self): @unittest.skipUnless( os.environ.get('TEST_CLI') or os.environ.get('CI'), - 'skipping CLI test which affects logging') + 'skipping CLI test which breaks test logging') def test_predict_here(self): sio = io.StringIO() with temporarily_set_logger_level('version_query', logging.ERROR), \ diff --git a/test/test_git.py b/test/test_git.py index 543958e..41bcdf3 100644 --- a/test/test_git.py +++ b/test/test_git.py @@ -81,7 +81,7 @@ def test_nonversion_tags(self): self.assertEqual(version, upcoming_version) @unittest.skipUnless( - os.environ.get('TEST_LONG', False) or os.environ.get('CI'), 'skipping long test') + os.environ.get('TEST_LONG') or os.environ.get('CI'), 'skipping long test') def test_too_long_no_tag(self): self.git_commit_new_file() self.repo.create_tag('v4.0.0') diff --git a/test/test_query.py b/test/test_query.py index 5bae762..3459d72 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -61,7 +61,7 @@ def _query_test_case(self, paths, query_function): _LOG.debug('%s: %s', path, version) @unittest.skipUnless( - os.environ.get('TEST_LONG', False) or os.environ.get('CI'), 'skipping long test') + os.environ.get('TEST_LONG') or os.environ.get('CI'), 'skipping long test') def test_query_git_repo(self): self._check_examples_count('git repo', GIT_REPO_EXAMPLES) _LOG.debug('testing query_git_repo() on %i repositories', len(GIT_REPO_EXAMPLES)) @@ -85,7 +85,7 @@ def test_predict_caller_bad(self): project_file_path.unlink() @unittest.skipUnless( - os.environ.get('TEST_LONG', False) or os.environ.get('CI'), 'skipping long test') + os.environ.get('TEST_LONG') or os.environ.get('CI'), 'skipping long test') def test_predict_git_repo(self): _LOG.debug('testing predict_git_repo() on %i repositories', len(GIT_REPO_EXAMPLES)) self._query_test_case(GIT_REPO_EXAMPLES, predict_git_repo) From b52da70fff3db835a0a6d07dd5836b33524d3328 Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 15:23:13 +0900 Subject: [PATCH 10/14] fix: ignore empty, "v" and "ver" tags --- version_query/git_query.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/version_query/git_query.py b/version_query/git_query.py index 380e407..188f5aa 100644 --- a/version_query/git_query.py +++ b/version_query/git_query.py @@ -14,20 +14,22 @@ def preprocess_git_version_tag(tag: str): """Remove a prefix from a version tag.""" - if tag.startswith('ver'): + if tag.startswith('ver') and len(tag) > 3: return tag[3:] - if tag.startswith('v'): + if tag.startswith('v') and len(tag) > 1: return tag[1:] if tag and tag[0] in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'): return tag - raise ValueError(f'given tag "{tag}" does not appear to be a version tag') + raise ValueError(f'the tag "{tag}" does not appear to be a version tag') def _git_version_tags(repo: git.Repo) -> t.Mapping[git.Tag, Version]: versions = {} for tag in repo.tags: + if tag.name is None or not tag.name: + continue try: - tag_str = preprocess_git_version_tag(str(tag)) + tag_str = preprocess_git_version_tag(tag.name) except ValueError: _LOG.debug('%s: ignoring non-version tag %s', repo, tag) continue @@ -35,7 +37,7 @@ def _git_version_tags(repo: git.Repo) -> t.Mapping[git.Tag, Version]: versions[tag] = Version.from_str(tag_str) except ValueError: # except packaging.version.InvalidVersion: - _LOG.warning('%s: failed to convert %s to version', repo, tag_str) + _LOG.warning('%s: failed to convert %s (%r) to version', repo, tag.name, tag_str) continue return versions From 31919979361d8c8fc75a05c4c79572d21ab50a1d Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 15:23:48 +0900 Subject: [PATCH 11/14] fix: update supported OS configs --- .github/workflows/python.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 76c1c4a..12771e7 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -12,12 +12,10 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.10', 'pypy3.10', '3.11', '3.12', '3.13'] + python-version: ['3.10', '3.11', 'pypy3.11', '3.12', '3.13'] exclude: - os: macos-latest python-version: '3.10' - - os: macos-latest - python-version: 'pypy3.10' steps: - uses: actions/checkout@v5 with: From 8d870e4c43187f414019f559b868335fb3d1862e Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 17:38:25 +0900 Subject: [PATCH 12/14] fix: improve bad tag handling --- test/test_git.py | 11 +++++++++++ version_query/git_query.py | 10 ++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/test/test_git.py b/test/test_git.py index 41bcdf3..c3c44d7 100644 --- a/test/test_git.py +++ b/test/test_git.py @@ -80,6 +80,17 @@ def test_nonversion_tags(self): version.local = (f'git{self.repo_head_hexsha}',) self.assertEqual(version, upcoming_version) + def test_too_short_version_tag(self): + self.git_commit_new_file() + self.repo.create_tag('v1.0') + self.git_commit_new_file() + self.repo.create_tag('v') + self.git_commit_new_file() + self.repo.create_tag('ver') + current_version = query_git_repo(self.repo_path) + _LOG.debug('current version is %s', current_version) + self.assertEqual(current_version.to_str(), '1.0') + @unittest.skipUnless( os.environ.get('TEST_LONG') or os.environ.get('CI'), 'skipping long test') def test_too_long_no_tag(self): diff --git a/version_query/git_query.py b/version_query/git_query.py index 188f5aa..510b7a1 100644 --- a/version_query/git_query.py +++ b/version_query/git_query.py @@ -14,9 +14,13 @@ def preprocess_git_version_tag(tag: str): """Remove a prefix from a version tag.""" - if tag.startswith('ver') and len(tag) > 3: + if tag.startswith('ver'): + if len(tag) == 3: + raise ValueError(f'the tag "{tag}" does not contain any version information') return tag[3:] - if tag.startswith('v') and len(tag) > 1: + if tag.startswith('v'): + if len(tag) == 1: + raise ValueError(f'the tag "{tag}" does not contain any version information') return tag[1:] if tag and tag[0] in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'): return tag @@ -26,8 +30,6 @@ def preprocess_git_version_tag(tag: str): def _git_version_tags(repo: git.Repo) -> t.Mapping[git.Tag, Version]: versions = {} for tag in repo.tags: - if tag.name is None or not tag.name: - continue try: tag_str = preprocess_git_version_tag(tag.name) except ValueError: From 03de5287fe4fd77d0f0129869c434c5d4043311c Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 18:02:29 +0900 Subject: [PATCH 13/14] feat: support python 3.14 --- .github/workflows/python.yml | 4 ++-- Dockerfile | 2 +- setup.py | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 12771e7..315f6b0 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.10', '3.11', 'pypy3.11', '3.12', '3.13'] + python-version: ['3.10', '3.11', 'pypy3.11', '3.12', '3.13', '3.14'] exclude: - os: macos-latest python-version: '3.10' @@ -50,7 +50,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' - run: pip install build~=1.2 - run: python -m build - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/Dockerfile b/Dockerfile index d72808a..494c6fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG PYTHON_VERSION="3.13" +ARG PYTHON_VERSION="3.14" FROM python:${PYTHON_VERSION} diff --git a/setup.py b/setup.py index ffe4c0e..01e604e 100644 --- a/setup.py +++ b/setup.py @@ -24,6 +24,7 @@ class Package(boilerplates.setup.Package): 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3.14', 'Programming Language :: Python :: 3 :: Only', 'Topic :: Software Development :: Version Control', 'Topic :: Software Development :: Version Control :: Git', From bae8823187417529087a5d88148612d73166bedd Mon Sep 17 00:00:00 2001 From: Mateusz Bysiek <1270332+mbdevpl@users.noreply.github.com> Date: Wed, 6 May 2026 18:03:13 +0900 Subject: [PATCH 14/14] chore: don't support 3.9 --- README.rst | 2 +- setup.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 28ab667..adb8824 100644 --- a/README.rst +++ b/README.rst @@ -517,7 +517,7 @@ using version-query without any issues. Requirements ============ -Python version 3.9 or later. +Python version 3.10 or later. Python libraries as specified in ``_. diff --git a/setup.py b/setup.py index 01e604e..287d98f 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,6 @@ class Package(boilerplates.setup.Package): 'Operating System :: MacOS', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12',