@@ -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,9 @@ 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+ sub_parser_action = action_parsers .get (action_name )
276+ if sub_parser_action is None :
277+ sub_parser_action = sub_parser .add_parser (action_name )
272278 # Get the attributes for URL/path construction
273279 if mgr_cls ._from_parent_attrs :
274280 for x in mgr_cls ._from_parent_attrs :
@@ -298,13 +304,17 @@ def _populate_sub_parser_by_class(
298304 if mgr_cls .__name__ in cli .custom_actions :
299305 name = mgr_cls .__name__
300306 for action_name in cli .custom_actions [name ]:
301- sub_parser_action = sub_parser .add_parser (action_name )
307+ sub_parser_action = action_parsers .get (action_name )
308+ if sub_parser_action is None :
309+ sub_parser_action = sub_parser .add_parser (action_name )
302310 if mgr_cls ._from_parent_attrs :
303311 for x in mgr_cls ._from_parent_attrs :
304312 sub_parser_action .add_argument (
305313 f"--{ x .replace ('_' , '-' )} " , required = True
306314 )
307- sub_parser_action .add_argument ("--sudo" , required = False )
315+ sub_parser_action .sub_parser_action .add_argument (
316+ "--sudo" , required = False
317+ )
308318
309319 required , optional , dummy = cli .custom_actions [name ][action_name ]
310320 for x in required :
@@ -326,16 +336,15 @@ def extend_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
326336 subparsers .required = True
327337
328338 # populate argparse for all Gitlab Object
329- classes = []
339+ classes = set ()
330340 for cls in gitlab .v4 .objects .__dict__ .values ():
331341 if not isinstance (cls , type ):
332342 continue
333343 if issubclass (cls , gitlab .base .RESTManager ):
334344 if cls ._obj_cls is not None :
335- classes .append (cls ._obj_cls )
336- classes .sort (key = operator .attrgetter ("__name__" ))
345+ classes .add (cls ._obj_cls )
337346
338- for cls in classes :
347+ for cls in sorted ( classes , key = operator . attrgetter ( "__name__" )) :
339348 arg_name = cli .cls_to_what (cls )
340349 object_group = subparsers .add_parser (arg_name )
341350
0 commit comments