From 5f2e10273a7459721225586d8ea795fdcd5c86ca Mon Sep 17 00:00:00 2001 From: Andy Mikhaylenko Date: Sun, 1 Jun 2025 21:25:30 +0200 Subject: [PATCH 1/2] chore!: drop support for Python 3.8 --- .github/workflows/lint-and-test.yml | 2 +- CHANGELOG.rst | 7 +++++++ docs/index.rst | 2 +- pyproject.toml | 3 +-- tests/test_mapping_policies.py | 5 ----- tox.ini | 2 -- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/lint-and-test.yml b/.github/workflows/lint-and-test.yml index 1ea274a..09e6dfe 100644 --- a/.github/workflows/lint-and-test.yml +++ b/.github/workflows/lint-and-test.yml @@ -17,11 +17,11 @@ jobs: strategy: matrix: python-version: - - '3.8' - '3.9' - '3.10' - '3.11' - '3.12' + - '3.13' - 'pypy-3.9' - 'pypy-3.10' steps: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a640a82..73a75bf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,13 @@ Changelog ========= +Version 0.31.3 (IN DEVELOPMENT) +------------------------------- + +Backward incompatible changes: + +- Dropped support for Python 3.8. + Version 0.31.3 (2024-07-13) --------------------------- diff --git a/docs/index.rst b/docs/index.rst index ffe657b..43e161b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ Dependencies ------------ The `argh` library is supported (and tested unless otherwise specified) -on the following versions of Python: 3.8, 3.9, 3.10, 3.11, 3.12, 3.13. +on the following versions of Python: 3.9, 3.10, 3.11, 3.12, 3.13. If you need support for ancient Pythons, please use the following versions of Argh (the numeric puns were semi-intentional): diff --git a/pyproject.toml b/pyproject.toml index 83e4761..a2d203a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "argh" version = "0.31.3" description = "Plain Python functions as CLI commands without boilerplate" readme = "README.rst" -requires-python = ">=3.8" +requires-python = ">=3.9" license = { file = "COPYING.LESSER" } authors = [ { name = "Andy Mikhaylenko", email = "neithere@gmail.com" }, @@ -31,7 +31,6 @@ classifiers = [ "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", diff --git a/tests/test_mapping_policies.py b/tests/test_mapping_policies.py index e77e122..1370ecd 100644 --- a/tests/test_mapping_policies.py +++ b/tests/test_mapping_policies.py @@ -75,11 +75,6 @@ def func(*file_paths) -> str: parser = _make_parser_for_function(func, name_mapping_policy=name_mapping_policy) expected_usage = "usage: test [-h] [file-paths ...]" - # TODO: remove once we drop support for Python 3.8 - if sys.version_info < (3, 9): - # https://github.com/python/cpython/issues/82619 - expected_usage = "usage: test [-h] [file-paths [file-paths ...]]" - assert_usage(parser, expected_usage) diff --git a/tox.ini b/tox.ini index 52615c0..157970c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,5 @@ [tox] envlist = - py38 py39 py310 py311 @@ -17,7 +16,6 @@ skip_missing_interpreters = true [gh-actions] # https://github.com/ymyzk/tox-gh-actions python = - 3.8: py38 3.9: py39 3.10: py310 3.11: py311,lint,as-module From 699568ad674c5ea26d361202c386a8a8a82ec8ad Mon Sep 17 00:00:00 2001 From: Andy Mikhaylenko Date: Sun, 1 Jun 2025 21:28:53 +0200 Subject: [PATCH 2/2] fix(test): tests were broken under Python 3.14.0b2 (fixes #239) --- .github/workflows/lint-and-test.yml | 1 + CHANGELOG.rst | 4 ++++ docs/index.rst | 2 +- pyproject.toml | 1 + tests/base.py | 7 ------- tests/test_integration.py | 20 +++++++++++++------- tests/test_mapping_policies.py | 1 - tox.ini | 10 +++------- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/lint-and-test.yml b/.github/workflows/lint-and-test.yml index 09e6dfe..00b25ce 100644 --- a/.github/workflows/lint-and-test.yml +++ b/.github/workflows/lint-and-test.yml @@ -22,6 +22,7 @@ jobs: - '3.11' - '3.12' - '3.13' + - '3.14' - 'pypy-3.9' - 'pypy-3.10' steps: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 73a75bf..a6378cb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,10 @@ Backward incompatible changes: - Dropped support for Python 3.8. +Enhancements: + +- Added support for Python 3.14. + Version 0.31.3 (2024-07-13) --------------------------- diff --git a/docs/index.rst b/docs/index.rst index 43e161b..780ab16 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ Dependencies ------------ The `argh` library is supported (and tested unless otherwise specified) -on the following versions of Python: 3.9, 3.10, 3.11, 3.12, 3.13. +on the following versions of Python: 3.9, 3.10, 3.11, 3.12, 3.13, 3.14. If you need support for ancient Pythons, please use the following versions of Argh (the numeric puns were semi-intentional): diff --git a/pyproject.toml b/pyproject.toml index a2d203a..3de7fa7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: User Interfaces", diff --git a/tests/base.py b/tests/base.py index 7710443..a031f25 100644 --- a/tests/base.py +++ b/tests/base.py @@ -4,8 +4,6 @@ """ import io -import os -import sys from collections import namedtuple from argh import ArghParser @@ -72,8 +70,3 @@ def run(parser, command_string, kwargs=None, exit=False): raise AssertionError("Did not exit") return result.exit_code return result - - -def get_usage_string(definitions="{cmd} ..."): - prog = os.path.basename(sys.argv[0]) - return "usage: " + prog + " [-h] " + definitions + "\n\n" diff --git a/tests/test_integration.py b/tests/test_integration.py index 8839265..6fc8a17 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -17,7 +17,7 @@ from argh.utils import unindent from .base import CmdResult as R -from .base import DebugArghParser, get_usage_string, run +from .base import DebugArghParser, run if sys.version_info < (3, 10): HELP_OPTIONS_LABEL = "optional arguments" @@ -796,11 +796,17 @@ def func(): parser = DebugArghParser() parser.set_default_command(func) - assert unindent(func.__doc__) in parser.format_help() + docstring = func.__doc__ + assert docstring + assert unindent(docstring) in parser.format_help() def test_prog(capsys: pytest.CaptureFixture[str]): - "Program name propagates from sys.argv[0]" + """ + Program name propagates to the usage string. + It's not just sys.argv[0], the logic is a bit more complicated in argparse, + so we just reuse whatever it has produced. + """ def cmd(*, foo=1): return foo @@ -808,10 +814,12 @@ def cmd(*, foo=1): parser = DebugArghParser() parser.add_commands([cmd]) - usage = get_usage_string() + usage = f"usage: {parser.prog} [-h]" - assert run(parser, "-h", exit=True) == 0 + exit_code = run(parser, "-h", exit=True) captured = capsys.readouterr() + + assert exit_code == 0 assert captured.out.startswith(usage) @@ -822,8 +830,6 @@ def cmd(*, foo=1): parser = DebugArghParser() parser.set_default_command(cmd) - get_usage_string("[-f FOO]") - assert run(parser, "--foo 1") == R(out="1\n", err="") assert run(parser, "--bar 1", exit=True) == "unrecognized arguments: --bar 1" assert run(parser, "--bar 1", exit=False, kwargs={"skip_unknown_args": True}) == R( diff --git a/tests/test_mapping_policies.py b/tests/test_mapping_policies.py index 1370ecd..b704733 100644 --- a/tests/test_mapping_policies.py +++ b/tests/test_mapping_policies.py @@ -1,4 +1,3 @@ -import sys from argparse import ArgumentParser, Namespace from typing import Callable, List, Optional diff --git a/tox.ini b/tox.ini index 157970c..afab154 100644 --- a/tox.ini +++ b/tox.ini @@ -5,8 +5,8 @@ envlist = py311 py312 py313 + py314 pypy3 - as-module lint docs skipdist = true @@ -21,6 +21,7 @@ python = 3.11: py311,lint,as-module 3.12: py312 3.13: py313 + 3.14: py314 pypy-3.9: pypy3 pypy-3.10: pypy3 @@ -28,15 +29,10 @@ python = description = run unit tests extras = test commands = - pytest --cov=argh --cov-report html --cov-fail-under 100 {posargs:tests} + python -m pytest --cov=argh --cov-report html --cov-fail-under 100 {posargs:tests} setenv = PYTHONPATH=src -[testenv:as-module] -description = run unit tests, ensure they don't depend on specific prog name -commands = - python -m pytest {posargs:tests} - [testenv:docs] description = build the HTML docs using sphinx-build extras = docs