Skip to content

Commit 7d5a0c9

Browse files
authored
Merge pull request #2014 from python-gitlab/jlvillal/python3.11beta1
fix: duplicate subparsers being added to argparse
2 parents 6b47c26 + f553fd3 commit 7d5a0c9

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

gitlab/v4/cli.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,15 @@ def _populate_sub_parser_by_class(
200200
mgr_cls_name = f"{cls.__name__}Manager"
201201
mgr_cls = getattr(gitlab.v4.objects, mgr_cls_name)
202202

203+
action_parsers: Dict[str, argparse.ArgumentParser] = {}
203204
for action_name in ["list", "get", "create", "update", "delete"]:
204205
if not hasattr(mgr_cls, action_name):
205206
continue
206207

207-
sub_parser_action = sub_parser.add_parser(action_name)
208+
sub_parser_action = sub_parser.add_parser(
209+
action_name, conflict_handler="resolve"
210+
)
211+
action_parsers[action_name] = sub_parser_action
208212
sub_parser_action.add_argument("--sudo", required=False)
209213
if mgr_cls._from_parent_attrs:
210214
for x in mgr_cls._from_parent_attrs:
@@ -268,7 +272,11 @@ def _populate_sub_parser_by_class(
268272
if cls.__name__ in cli.custom_actions:
269273
name = cls.__name__
270274
for action_name in cli.custom_actions[name]:
271-
sub_parser_action = sub_parser.add_parser(action_name)
275+
# NOTE(jlvillal): If we put a function for the `default` value of
276+
# the `get` it will always get called, which will break things.
277+
sub_parser_action = action_parsers.get(action_name)
278+
if sub_parser_action is None:
279+
sub_parser_action = sub_parser.add_parser(action_name)
272280
# Get the attributes for URL/path construction
273281
if mgr_cls._from_parent_attrs:
274282
for x in mgr_cls._from_parent_attrs:
@@ -298,7 +306,11 @@ def _populate_sub_parser_by_class(
298306
if mgr_cls.__name__ in cli.custom_actions:
299307
name = mgr_cls.__name__
300308
for action_name in cli.custom_actions[name]:
301-
sub_parser_action = sub_parser.add_parser(action_name)
309+
# NOTE(jlvillal): If we put a function for the `default` value of
310+
# the `get` it will always get called, which will break things.
311+
sub_parser_action = action_parsers.get(action_name)
312+
if sub_parser_action is None:
313+
sub_parser_action = sub_parser.add_parser(action_name)
302314
if mgr_cls._from_parent_attrs:
303315
for x in mgr_cls._from_parent_attrs:
304316
sub_parser_action.add_argument(
@@ -326,16 +338,15 @@ def extend_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
326338
subparsers.required = True
327339

328340
# populate argparse for all Gitlab Object
329-
classes = []
341+
classes = set()
330342
for cls in gitlab.v4.objects.__dict__.values():
331343
if not isinstance(cls, type):
332344
continue
333345
if issubclass(cls, gitlab.base.RESTManager):
334346
if cls._obj_cls is not None:
335-
classes.append(cls._obj_cls)
336-
classes.sort(key=operator.attrgetter("__name__"))
347+
classes.add(cls._obj_cls)
337348

338-
for cls in classes:
349+
for cls in sorted(classes, key=operator.attrgetter("__name__")):
339350
arg_name = cli.cls_to_what(cls)
340351
object_group = subparsers.add_parser(arg_name)
341352

tests/unit/v4/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)