Skip to content

Commit 8cce8ea

Browse files
committed
shtab support for optionals parsed as positionals
1 parent 69b7e33 commit 8cce8ea

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Added
1919
^^^^^
2020
- ``shtab`` hint for positionals in bash now includes the argument name (`#699
2121
<https://github.com/omni-us/jsonargparse/pull/699>`__).
22+
- ``shtab`` support for optionals parsed as positionals (`#700
23+
<https://github.com/omni-us/jsonargparse/pull/700>`__).
2224

2325
Changed
2426
^^^^^^^

jsonargparse/_completions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
from collections import defaultdict
77
from contextlib import contextmanager, suppress
88
from contextvars import ContextVar
9+
from copy import deepcopy
910
from enum import Enum
1011
from importlib.util import find_spec
1112
from subprocess import PIPE, Popen
1213
from typing import List, Literal, Union
1314

1415
from ._actions import ActionConfigFile, _ActionConfigLoad, _ActionHelpClassPath, remove_actions
16+
from ._common import get_optionals_as_positionals_actions, get_parsing_setting
1517
from ._parameter_resolvers import get_signature_parameters
1618
from ._typehints import (
1719
ActionTypeHint,
@@ -129,6 +131,12 @@ def shtab_prepare_actions(parser) -> None:
129131
if parser._subcommands_action:
130132
for subparser in parser._subcommands_action._name_parser_map.values():
131133
shtab_prepare_actions(subparser)
134+
if get_parsing_setting("parse_optionals_as_positionals"):
135+
for action in get_optionals_as_positionals_actions(parser):
136+
clone = deepcopy(action)
137+
clone.option_strings = []
138+
clone.nargs = "?"
139+
parser._actions.append(clone)
132140
for action in parser._actions:
133141
shtab_prepare_action(action, parser)
134142

jsonargparse_tests/test_parsing_settings.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import re
22
from dataclasses import dataclass
3+
from importlib.util import find_spec
34
from typing import Literal, Optional
45
from unittest.mock import patch
56

@@ -8,6 +9,7 @@
89
from jsonargparse import ActionYesNo, ArgumentError, Namespace, set_parsing_settings
910
from jsonargparse._common import get_parsing_setting
1011
from jsonargparse_tests.conftest import capture_logs, get_parse_args_stdout, get_parser_help
12+
from jsonargparse_tests.test_shtab import assert_bash_typehint_completions
1113
from jsonargparse_tests.test_typehints import Optimizer
1214

1315

@@ -152,3 +154,24 @@ def test_optionals_as_positionals_unsupported_arguments(parser):
152154

153155
help_str = get_parse_args_stdout(parser, ["--o1.help=Adam"])
154156
assert "extra positionals are parsed as optionals in the order shown above" not in help_str
157+
158+
159+
@pytest.mark.skipif(not find_spec("shtab"), reason="shtab package is required")
160+
def test_shtab_bash_optionals_as_positionals(parser, subtests):
161+
set_parsing_settings(parse_optionals_as_positionals=True)
162+
parser.prog = "tool"
163+
164+
parser.add_argument("job", type=str)
165+
parser.add_argument("--amount", type=int, default=0)
166+
parser.add_argument("--flag", type=bool, default=False)
167+
assert_bash_typehint_completions(
168+
subtests,
169+
parser,
170+
[
171+
("job", str, "", [], None),
172+
("job", str, "easy", [], None),
173+
("amount", int, "easy ", [], None),
174+
("amount", int, "easy 10", [], None),
175+
("flag", bool, "easy 10 x", [], "0/2"),
176+
],
177+
)

0 commit comments

Comments
 (0)