sphinx-argparse-cli 1.21.4__tar.gz → 1.22.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/PKG-INFO +2 -1
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/pyproject.toml +2 -1
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/src/sphinx_argparse_cli/_logic.py +54 -63
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/src/sphinx_argparse_cli/version.py +2 -2
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/tests/test_logic.py +7 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/.gitignore +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/LICENSE.txt +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/README.md +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/src/sphinx_argparse_cli/__init__.py +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/src/sphinx_argparse_cli/py.typed +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/tests/complex.txt +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/tests/complex_pre_310.txt +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/tests/conftest.py +0 -0
- {sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/tests/test_sphinx_argparse_cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sphinx-argparse-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.22.1
|
|
4
4
|
Summary: render CLI arguments (sub-commands friendly) defined by argparse module
|
|
5
5
|
Project-URL: Documentation, https://github.com/tox-dev/sphinx-argparse-cli#sphinx-argparse-cli
|
|
6
6
|
Project-URL: Homepage, https://github.com/tox-dev/sphinx-argparse-cli
|
|
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.13
|
|
24
24
|
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
25
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
27
|
Classifier: Topic :: Documentation
|
|
27
28
|
Classifier: Topic :: Documentation :: Sphinx
|
|
@@ -31,6 +31,7 @@ classifiers = [
|
|
|
31
31
|
"Programming Language :: Python :: 3.12",
|
|
32
32
|
"Programming Language :: Python :: 3.13",
|
|
33
33
|
"Programming Language :: Python :: 3.14",
|
|
34
|
+
"Programming Language :: Python :: 3.15",
|
|
34
35
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
35
36
|
"Topic :: Documentation",
|
|
36
37
|
"Topic :: Documentation :: Sphinx",
|
|
@@ -128,7 +129,7 @@ builtin = "clear,usage,en-GB_to_en-US"
|
|
|
128
129
|
count = true
|
|
129
130
|
|
|
130
131
|
[tool.pyproject-fmt]
|
|
131
|
-
max_supported_python = "3.
|
|
132
|
+
max_supported_python = "3.15"
|
|
132
133
|
|
|
133
134
|
[tool.ty]
|
|
134
135
|
environment.python-version = "3.14"
|
|
@@ -16,6 +16,7 @@ from argparse import (
|
|
|
16
16
|
)
|
|
17
17
|
from collections import defaultdict
|
|
18
18
|
from contextlib import contextmanager
|
|
19
|
+
from functools import cached_property
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
from typing import TYPE_CHECKING, Any, ClassVar, Final, cast
|
|
21
22
|
from unittest.mock import patch
|
|
@@ -46,9 +47,8 @@ from sphinx.util.docutils import SphinxDirective
|
|
|
46
47
|
from sphinx.util.logging import getLogger
|
|
47
48
|
|
|
48
49
|
if TYPE_CHECKING:
|
|
49
|
-
from collections.abc import Iterator
|
|
50
|
+
from collections.abc import Callable, Iterator
|
|
50
51
|
|
|
51
|
-
from docutils.parsers.rst.states import RSTState, RSTStateMachine
|
|
52
52
|
from sphinx.domains.std import StandardDomain
|
|
53
53
|
from sphinx.util.logging import SphinxLoggerAdapter
|
|
54
54
|
|
|
@@ -77,66 +77,56 @@ class SphinxArgparseCli(SphinxDirective):
|
|
|
77
77
|
"force_refs_lower": flag,
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
self,
|
|
82
|
-
name: str,
|
|
83
|
-
arguments: list[str],
|
|
84
|
-
options: dict[str, str | None],
|
|
85
|
-
content: StringList,
|
|
86
|
-
lineno: int,
|
|
87
|
-
content_offset: int,
|
|
88
|
-
block_text: str,
|
|
89
|
-
state: RSTState,
|
|
90
|
-
state_machine: RSTStateMachine,
|
|
91
|
-
) -> None:
|
|
92
|
-
options.setdefault("group_title_prefix", None)
|
|
93
|
-
options.setdefault("group_sub_title_prefix", None)
|
|
94
|
-
super().__init__(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
|
|
95
|
-
self._parser: ArgumentParser | None = None
|
|
96
|
-
self._std_domain: StandardDomain = cast("StandardDomain", self.env.get_domain("std"))
|
|
97
|
-
self._raw_format: bool = False
|
|
98
|
-
self._make_id = make_id_lower if "force_refs_lower" in self.options else make_id
|
|
99
|
-
|
|
100
|
-
@property
|
|
80
|
+
@cached_property
|
|
101
81
|
def parser(self) -> ArgumentParser:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
82
|
+
module_name, attr_name = self.options["module"], self.options["func"]
|
|
83
|
+
try:
|
|
84
|
+
module = __import__(module_name, fromlist=[attr_name])
|
|
85
|
+
except ImportError:
|
|
86
|
+
msg = f"Failed to import module {module_name!r}"
|
|
87
|
+
raise self.error(msg) # noqa: B904
|
|
88
|
+
try:
|
|
89
|
+
parser_creator = getattr(module, attr_name)
|
|
90
|
+
except AttributeError:
|
|
91
|
+
del sys.modules[module_name]
|
|
92
|
+
msg = f"Module {module_name!r} has no attribute {attr_name!r}"
|
|
93
|
+
raise self.error(msg) # noqa: B904
|
|
94
|
+
parser: ArgumentParser | None = None
|
|
95
|
+
if "hook" in self.options:
|
|
96
|
+
original_parse_known_args = ArgumentParser.parse_known_args
|
|
97
|
+
ArgumentParser.parse_known_args = _parse_known_args_hook # type: ignore[method-assign,assignment]
|
|
109
98
|
try:
|
|
110
|
-
parser_creator
|
|
111
|
-
except
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
ArgumentParser.parse_known_args = _parse_known_args_hook # type: ignore[method-assign,assignment]
|
|
118
|
-
try:
|
|
119
|
-
parser_creator()
|
|
120
|
-
except HookError as hooked:
|
|
121
|
-
self._parser = hooked.parser
|
|
122
|
-
finally:
|
|
123
|
-
ArgumentParser.parse_known_args = original_parse_known_args
|
|
124
|
-
else:
|
|
125
|
-
self._parser = parser_creator()
|
|
99
|
+
parser_creator()
|
|
100
|
+
except HookError as hooked:
|
|
101
|
+
parser = hooked.parser
|
|
102
|
+
finally:
|
|
103
|
+
ArgumentParser.parse_known_args = original_parse_known_args
|
|
104
|
+
else:
|
|
105
|
+
parser = parser_creator()
|
|
126
106
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
107
|
+
del sys.modules[module_name]
|
|
108
|
+
if parser is None:
|
|
109
|
+
msg = "Failed to hook argparse to get ArgumentParser"
|
|
110
|
+
raise self.error(msg)
|
|
131
111
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
112
|
+
if "prog" in self.options:
|
|
113
|
+
old_prog, new_prog = parser.prog, self.options["prog"]
|
|
114
|
+
parser.prog = new_prog
|
|
115
|
+
_update_sub_parser_prog(parser, old_prog, new_prog)
|
|
116
|
+
return parser
|
|
136
117
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return self.
|
|
118
|
+
@cached_property
|
|
119
|
+
def _std_domain(self) -> StandardDomain:
|
|
120
|
+
return cast("StandardDomain", self.env.get_domain("std"))
|
|
121
|
+
|
|
122
|
+
@cached_property
|
|
123
|
+
def _make_id(self) -> Callable[[str], str]:
|
|
124
|
+
return make_id_lower if "force_refs_lower" in self.options else make_id
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def _raw_format(self) -> bool:
|
|
128
|
+
formatter = self.parser.formatter_class
|
|
129
|
+
return isinstance(formatter, type) and issubclass(formatter, RawDescriptionHelpFormatter)
|
|
140
130
|
|
|
141
131
|
def _load_sub_parsers(
|
|
142
132
|
self, sub_parser: _SubParsersAction[ArgumentParser]
|
|
@@ -159,7 +149,8 @@ class SphinxArgparseCli(SphinxDirective):
|
|
|
159
149
|
|
|
160
150
|
if parser._subparsers: # noqa: SLF001
|
|
161
151
|
sub_sub_parser: _SubParsersAction[ArgumentParser] = parser._subparsers._group_actions[0] # type: ignore[assignment] # noqa: SLF001
|
|
162
|
-
|
|
152
|
+
if isinstance(sub_sub_parser, _SubParsersAction):
|
|
153
|
+
yield from self._load_sub_parsers(sub_sub_parser)
|
|
163
154
|
|
|
164
155
|
def _iter_sub_commands(self) -> Iterator[tuple[list[str], str, ArgumentParser]]:
|
|
165
156
|
top_sub_parser = self.parser._subparsers # noqa: SLF001
|
|
@@ -202,7 +193,7 @@ class SphinxArgparseCli(SphinxDirective):
|
|
|
202
193
|
|
|
203
194
|
return [home_section]
|
|
204
195
|
|
|
205
|
-
def _pre_format(self, block:
|
|
196
|
+
def _pre_format(self, block: str | None) -> paragraph | literal_block | None:
|
|
206
197
|
if block is None:
|
|
207
198
|
return None
|
|
208
199
|
if self._raw_format and "\n" in block:
|
|
@@ -214,8 +205,8 @@ class SphinxArgparseCli(SphinxDirective):
|
|
|
214
205
|
return para
|
|
215
206
|
|
|
216
207
|
def _mk_option_group(self, group: _ArgumentGroup, prefix: str, prog: str) -> section:
|
|
217
|
-
sub_title_prefix: str = self.options
|
|
218
|
-
title_prefix = self.options
|
|
208
|
+
sub_title_prefix: str = self.options.get("group_sub_title_prefix")
|
|
209
|
+
title_prefix = self.options.get("group_title_prefix")
|
|
219
210
|
title_text = self._build_opt_grp_title(group, prefix, prog, sub_title_prefix, title_prefix)
|
|
220
211
|
title_ref: str = f"{prefix}{' ' if prefix else ''}{group.title}"
|
|
221
212
|
ref_id = self._make_id(title_ref)
|
|
@@ -318,8 +309,8 @@ class SphinxArgparseCli(SphinxDirective):
|
|
|
318
309
|
self._std_domain.labels[name] = doc_name, ref_name, ref_title
|
|
319
310
|
|
|
320
311
|
def _mk_sub_command(self, aliases: list[str], help_msg: str, parser: ArgumentParser) -> section:
|
|
321
|
-
sub_title_prefix: str = self.options
|
|
322
|
-
title_prefix: str = self.options
|
|
312
|
+
sub_title_prefix: str = self.options.get("group_sub_title_prefix")
|
|
313
|
+
title_prefix: str = self.options.get("group_title_prefix")
|
|
323
314
|
|
|
324
315
|
if sys.version_info >= (3, 14): # pragma: >=3.14 cover
|
|
325
316
|
# https://github.com/python/cpython/issues/139809
|
{sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/src/sphinx_argparse_cli/version.py
RENAMED
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.
|
|
22
|
-
__version_tuple__ = version_tuple = (1,
|
|
21
|
+
__version__ = version = '1.22.1'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 22, 1)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -369,6 +369,13 @@ def test_subparsers(build_outcome: str) -> None:
|
|
|
369
369
|
assert '<section id="test-no_child-options">' in build_outcome
|
|
370
370
|
|
|
371
371
|
|
|
372
|
+
@pytest.mark.sphinx(buildername="html", testroot="subparsers-storeaction")
|
|
373
|
+
def test_subparsers_stoeaction(build_outcome: str) -> None:
|
|
374
|
+
assert '<section id="test-options">' in build_outcome
|
|
375
|
+
assert '<section id="test-subparser">' in build_outcome
|
|
376
|
+
assert '<section id="test-subparser-positional-arguments">' in build_outcome
|
|
377
|
+
|
|
378
|
+
|
|
372
379
|
@pytest.mark.sphinx(buildername="text", testroot="bad-module")
|
|
373
380
|
def test_bad_module(app: SphinxTestApp, warning: StringIO) -> None:
|
|
374
381
|
app.build()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sphinx_argparse_cli-1.21.4 → sphinx_argparse_cli-1.22.1}/src/sphinx_argparse_cli/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|