Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7ec3189

Browse files
authored
fix(cli): allow exclusive arguments as optional (#2770)
* fix(cli): allow exclusive arguments as optionalThe CLI takes its arguments from the RequiredOptional, which has three fields: required, optional, and exclusive. In practice, the exclusive options are not defined as either required or optional, and would not be allowed in the CLI. This changes that, so that exclusive options are also added to the argument parser. * fix(cli): inform argument parser that options are mutually exclusive * fix(cli): use correct exclusive options, add unit testCloses#2769
1 parent4e68d32 commit7ec3189

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

‎gitlab/v4/cli.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ def _populate_sub_parser_by_class(
262262
sub_parser_action.add_argument(
263263
f"--{x.replace('_','-')}",required=False
264264
)
265+
ifmgr_cls._create_attrs.exclusive:
266+
group=sub_parser_action.add_mutually_exclusive_group()
267+
forxinmgr_cls._create_attrs.exclusive:
268+
group.add_argument(f"--{x.replace('_','-')}")
265269

266270
ifaction_name=="update":
267271
ifcls._id_attrisnotNone:
@@ -280,6 +284,11 @@ def _populate_sub_parser_by_class(
280284
f"--{x.replace('_','-')}",required=False
281285
)
282286

287+
ifmgr_cls._update_attrs.exclusive:
288+
group=sub_parser_action.add_mutually_exclusive_group()
289+
forxinmgr_cls._update_attrs.exclusive:
290+
group.add_argument(f"--{x.replace('_','-')}")
291+
283292
ifcls.__name__incli.custom_actions:
284293
name=cls.__name__
285294
foraction_nameincli.custom_actions[name]:

‎tests/unit/test_cli.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
importgitlab.base
1212
fromgitlabimportcli
1313
fromgitlab.exceptionsimportGitlabError
14+
fromgitlab.mixinsimportCreateMixin,UpdateMixin
15+
fromgitlab.typesimportRequiredOptional
1416
fromgitlab.v4importcliasv4_cli
1517

1618

@@ -157,6 +159,65 @@ def test_v4_parser():
157159
assertactions["--name"].required
158160

159161

162+
deftest_extend_parser():
163+
classExceptionArgParser(argparse.ArgumentParser):
164+
deferror(self,message):
165+
"Raise error instead of exiting on invalid arguments, to make testing easier"
166+
raiseValueError(message)
167+
168+
classFake:
169+
_id_attr=None
170+
171+
classFakeManager(gitlab.base.RESTManager,CreateMixin,UpdateMixin):
172+
_obj_cls=Fake
173+
_create_attrs=RequiredOptional(
174+
required=("create",),
175+
optional=("opt_create",),
176+
exclusive=("create_a","create_b"),
177+
)
178+
_update_attrs=RequiredOptional(
179+
required=("update",),
180+
optional=("opt_update",),
181+
exclusive=("update_a","update_b"),
182+
)
183+
184+
parser=ExceptionArgParser()
185+
withmock.patch.dict(
186+
"gitlab.v4.objects.__dict__", {"FakeManager":FakeManager},clear=True
187+
):
188+
v4_cli.extend_parser(parser)
189+
190+
assertparser.parse_args(["fake","create","--create","1"])
191+
assertparser.parse_args(["fake","create","--create","1","--opt-create","1"])
192+
assertparser.parse_args(["fake","create","--create","1","--create-a","1"])
193+
assertparser.parse_args(["fake","create","--create","1","--create-b","1"])
194+
195+
withpytest.raises(ValueError):
196+
# missing required "create"
197+
parser.parse_args(["fake","create","--opt_create","1"])
198+
199+
withpytest.raises(ValueError):
200+
# both exclusive options
201+
parser.parse_args(
202+
["fake","create","--create","1","--create-a","1","--create-b","1"]
203+
)
204+
205+
assertparser.parse_args(["fake","update","--update","1"])
206+
assertparser.parse_args(["fake","update","--update","1","--opt-update","1"])
207+
assertparser.parse_args(["fake","update","--update","1","--update-a","1"])
208+
assertparser.parse_args(["fake","update","--update","1","--update-b","1"])
209+
210+
withpytest.raises(ValueError):
211+
# missing required "update"
212+
parser.parse_args(["fake","update","--opt_update","1"])
213+
214+
withpytest.raises(ValueError):
215+
# both exclusive options
216+
parser.parse_args(
217+
["fake","update","--update","1","--update-a","1","--update-b","1"]
218+
)
219+
220+
160221
@pytest.mark.skipif(sys.version_info< (3,8),reason="added in 3.8")
161222
deftest_legacy_display_without_fields_warns(fake_object_no_id):
162223
printer=v4_cli.LegacyPrinter()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp