Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declare 3.13 support and drop 3.9 #184

Merged
merged 1 commit into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,35 @@ concurrency:

jobs:
test:
name: test on CPython ${{ matrix.py }}
name: test ${{ matrix.py }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
py:
- "3.13"
- "3.12"
- "3.11"
- "3.10"
- "3.9"
steps:
- name: setup uv for tox
uses: yezz123/setup-uv@v4
- name: setup python for tox
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: install tox
run: python -m pip install tox-uv
run: uv pip install tox tox-uv --system
- uses: actions/checkout@v4
- name: setup python for test ${{ matrix.py }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.py }}
- name: Pick environment to run
run: |
import codecs; import os; import sys
env = f"TOXENV=py3{sys.version_info[1]}\n"
print(f"Picked:\n{env}for{sys.version}")
with codecs.open(os.environ["GITHUB_ENV"], "a", "utf-8") as file_handler:
file_handler.write(env)
shell: python
allow-prereleases: true
- name: setup test suite
run: tox -vv --notest
run: tox run -vv --notest --skip-missing-interpreters false -e ${{ matrix.py }}
- name: run test suite
run: tox --skip-pkg-install
env:
PYTEST_ADDOPTS: "-vv --durations=20"
CI_RUN: "yes"
DIFF_AGAINST: HEAD
run: tox run --skip-pkg-install -e ${{ matrix.py }}

check:
name: tox env ${{ matrix.tox_env }}
Expand All @@ -62,16 +53,18 @@ jobs:
tox_env:
- type
- dev
- pkg_check
- readme
steps:
- name: setup uv for tox
uses: yezz123/setup-uv@v4
- uses: actions/checkout@v4
- name: setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: install tox
run: python -m pip install tox
- name: run check for ${{ matrix.tox_env }}
run: python -m tox -e ${{ matrix.tox_env }}
env:
UPGRADE_ADVISORY: "yes"
run: uv pip install tox tox-uv --system
- name: Setup test suite
run: tox -vv --notest --skip-missing-interpreters false -e ${{ matrix.tox_env }}
- name: Run test suite
run: tox --skip-pkg-install -e ${{ matrix.tox_env }}
6 changes: 4 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: setup uv for tox
uses: yezz123/setup-uv@v4
- name: Install build
run: python -m pip install build
run: uv pip install build[uv] --system
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build package
run: pyproject-build -s -w . -o dist
run: pyproject-build --installer uv --sdist --wheel . --outdir dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.10.1
13 changes: 9 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ repos:
rev: 0.29.2
hooks:
- id: check-github-workflows
args: [ "--verbose" ]
args: ["--verbose"]
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
args: ["--write-changes"]
additional_dependencies: ["tomli>=2.0.1"]
- repo: https://github.com/tox-dev/tox-ini-fmt
rev: "1.3.1"
rev: "1.3.2"
hooks:
- id: tox-ini-fmt
args: ["-p", "fix"]
Expand All @@ -24,11 +24,16 @@ repos:
hooks:
- id: pyproject-fmt
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.6.3"
rev: "v0.6.4"
hooks:
- id: ruff-format
- id: ruff
args: ["--fix", "--unsafe-fixes", "--exit-non-zero-on-fix"]
- repo: https://github.com/rbubley/mirrors-prettier
rev: "v3.3.3"
hooks:
- id: prettier
args: ["--print-width=120", "--prose-wrap=always"]
- repo: meta
hooks:
- id: check-hooks-apply
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file.

- Allow to add content to directive.
- Fix Sphinx warnings about parallel reads.
- Add `force_args_lower` to enable `:ref:` links with mixed-case program names and arguments.
- Add `force_args_lower` to enable `:ref:` links with mixed-case program names and arguments.

## 1.13.1

Expand Down
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Render CLI arguments (sub-commands friendly) defined by the argparse module. For
python -m pip install sphinx-argparse-cli
```

[README.md](README.md)

## enable in your `conf.py`

```python
Expand All @@ -29,22 +31,23 @@ extensions = ["sphinx_argparse_cli"]

Within the reStructuredText files use the `sphinx_argparse_cli` directive that takes, at least, two arguments:

| Name | Description |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| module | the module path to where the parser is defined |
| func | the name of the function that once called with no arguments constructs the parser |
| prog | (optional) when provided, overwrites the `<prog>` name. |
| hook | (optional) hook `argparse` to retrieve the parser if `func` uses a parser instead of returning it. |
| title | (optional) when provided, overwrites the `<prog> - CLI interface` title added by default and when empty, will not be included |
| description | (optional) when provided, overwrites the description and when empty, will not be included |
| epilog | (optional) when provided, overwrites the epilog and when empty, will not be included |
| usage_width | (optional) how large should usage examples be - defaults to 100 character |
| usage_first | (optional) show usage before description |
| group_title_prefix | (optional) groups subsections title prefixes, accepts the string `{prog}` as a replacement for the program name - defaults to `{prog}` |
| group_sub_title_prefix | (optional) subcommands groups subsections title prefixes, accepts replacement of `{prog}` and `{subcommand}` for program and subcommand name - defaults to `{prog} {subcommand}` |
| no_default_values | (optional) suppresses generation of `default` entries |
| force_refs_lower | (optional) Sphinx `:ref:` only supports lower-case references. With this, any capital letter in generated reference anchors are lowered and given an `_` prefix (i.e. `A` becomes `_a`) |
For example:
| Name | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| module | the module path to where the parser is defined |
| func | the name of the function that once called with no arguments constructs the parser |
| prog | (optional) when provided, overwrites the `<prog>` name. |
| hook | (optional) hook `argparse` to retrieve the parser if `func` uses a parser instead of returning it. |
| title | (optional) when provided, overwrites the `<prog> - CLI interface` title added by default and when empty, will not be included |
| description | (optional) when provided, overwrites the description and when empty, will not be included |
| epilog | (optional) when provided, overwrites the epilog and when empty, will not be included |
| usage_width | (optional) how large should usage examples be - defaults to 100 character |
| usage_first | (optional) show usage before description |
| group_title_prefix | (optional) groups subsections title prefixes, accepts the string `{prog}` as a replacement for the program name - defaults to `{prog}` |
| group_sub_title_prefix | (optional) subcommands groups subsections title prefixes, accepts replacement of `{prog}` and `{subcommand}` for program and subcommand name - defaults to `{prog} {subcommand}` |
| no_default_values | (optional) suppresses generation of `default` entries |
| force_refs_lower | (optional) Sphinx `:ref:` only supports lower-case references. With this, any capital letter in generated reference anchors are lowered and given an `_` prefix (i.e. `A` becomes `_a`) |

> > > > > > > bda12fb (Declare 3.13 support and drop 3.9) For example:

```rst
.. sphinx_argparse_cli::
Expand Down Expand Up @@ -86,11 +89,12 @@ being `cli`:
- to refer to flag `--magic` of the `run` sub-command use ``:ref:`cli:tox-run---magic` ``.

Due to Sphinx's `:ref:` only supporting lower-case values, if you need to distinguish mixed case program names or
arguments, set the `:force_refs_lower:` argument. With this flag, captial-letters in references will be converted to
their lower-case counterpart and prefixed with an `_`. For example:
arguments, set the `:force_refs_lower:` argument. With this flag, captial-letters in references will be converted to
their lower-case counterpart and prefixed with an `_`. For example:

- A `prog` name `SampleProgram` will be referenced as ``:ref:`_sample_program...` ``.
- To distinguish between mixed case flags `-a` and `-A` use ``:ref:`_sample_program--a` `` and ``:ref:`_sample_program--_a` `` respectively
- To distinguish between mixed case flags `-a` and `-A` use ``:ref:`_sample_program--a` `` and
``:ref:`_sample_program--_a` `` respectively

Note that if you are _not_ concernced about using internal Sphinx `:ref:` cross-references, you may choose to leave this
off to maintain mixed-case anchors in your output HTML; but be aware that later enabling it will change your anchors in
Expand Down
25 changes: 16 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ license = "MIT"
maintainers = [
{ name = "Bernat Gabor", email = "gaborjbernat@gmail.com" },
] # noqa: E999
requires-python = ">=3.9"
requires-python = ">=3.10"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
Expand All @@ -27,10 +27,10 @@ classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3 :: Only",
"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 :: Implementation :: CPython",
"Topic :: Documentation",
"Topic :: Documentation :: Sphinx",
Expand All @@ -39,12 +39,12 @@ dynamic = [
"version",
]
dependencies = [
"sphinx>=7.3.7",
"sphinx>=8.0.2",
]
optional-dependencies.test = [
"covdefaults>=2.3",
"defusedxml>=0.7.1", # needed for sphinx.testing
"pytest>=8.2.2",
"pytest>=8.3.2",
"pytest-cov>=5",
]
urls.Documentation = "https://github.com/tox-dev/sphinx-argparse-cli#sphinx-argparse-cli"
Expand All @@ -64,8 +64,11 @@ version.source = "vcs"
line-length = 120

[tool.ruff]
target-version = "py38"
target-version = "py310"
line-length = 120
format.preview = true
format.docstring-code-line-length = 100
format.docstring-code-format = true
lint.select = [
"ALL",
]
Expand All @@ -76,6 +79,7 @@ lint.ignore = [
"CPY", # No copyright statements
"D203", # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible
"D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
"DOC", # not yet supported
"ISC001", # Conflict with formatter
"S104", # Possible binding to all interface
]
Expand All @@ -85,14 +89,14 @@ lint.per-file-ignores."roots/**/*.py" = [
"INP001", # no namespace
]
lint.per-file-ignores."tests/**/*.py" = [
"D", # don"t care about documentation in tests
"FBT", # don"t care about booleans as positional arguments in tests
"D", # don't care about documentation in tests
"FBT", # don't care about booleans as positional arguments in tests
"INP001", # no implicit namespace
"PLC2701", # private import
"PLR0913", # any number of arguments in tests
"PLR0917", # any number of arguments in tests
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
"S101", # asserts allowed in tests...
"S101", # asserts allowed in tests
"S603", # `subprocess` call: check for execution of untrusted input
]
lint.isort = { known-first-party = [
Expand All @@ -105,6 +109,9 @@ lint.isort = { known-first-party = [
builtin = "clear,usage,en-GB_to_en-US"
count = true

[tool.pyproject-fmt]
max_supported_python = "3.13"

[tool.coverage]
html.show_contexts = true
html.skip_covered = false
Expand All @@ -121,6 +128,6 @@ run.plugins = [
run.relative_files = true

[tool.mypy]
python_version = "3.11"
python_version = "3.12"
show_error_codes = true
strict = true
6 changes: 4 additions & 2 deletions src/sphinx_argparse_cli/_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
)
from collections import defaultdict
from pathlib import Path
from typing import TYPE_CHECKING, Any, ClassVar, Iterator, NamedTuple, cast
from typing import TYPE_CHECKING, Any, ClassVar, NamedTuple, cast

from docutils.nodes import (
Element,
Expand All @@ -41,6 +41,8 @@
from sphinx.util.logging import getLogger

if TYPE_CHECKING:
from collections.abc import Iterator

from docutils.parsers.rst.states import RSTState, RSTStateMachine


Expand Down Expand Up @@ -273,7 +275,7 @@ def _mk_option_line(self, action: Action, prefix: str) -> list_item:
"no_default_values" not in self.options
and action.default != SUPPRESS
and not re.match(r".*[ (]default[s]? .*", (action.help or ""))
and not isinstance(action, (_StoreTrueAction, _StoreFalseAction))
and not isinstance(action, _StoreTrueAction | _StoreFalseAction)
):
line += Text(" (default: ")
line += literal(text=str(action.default).replace(str(Path.cwd()), "{cwd}"))
Expand Down
3 changes: 1 addition & 2 deletions tests/test_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@

@pytest.fixture(scope="session")
def opt_grp_name() -> tuple[str, str]:
if sys.version_info >= (3, 10): # pragma: no branch # https://bugs.python.org/issue9694
return "options", "options" # pragma: no cover
return "options", "options" # pragma: no cover
return "optional arguments", "optional-arguments" # pragma: no cover


Expand Down
Loading
Loading