Skip to content

Parser

Custom ArgumentParser extension for queued argument collection and task execution.

This module provides a subclass of argparse.ArgumentParser that supports custom queue-based actions. It allows arguments to be collected in an ordered dictionary (queue) and grouped into tasks for sequential processing.

It registers the following custom actions: - "q": general Queue action similar to 'store' - "q_true": stores True in the queue, similar to 'store_true' - "q_false": stores False in the queue, similar to 'store_false' - "task": marks a task boundary and collects queued arguments

It registers the following custom type: - "kwargs": convert = arguments to dictionary with coresponding types

ArgumentParser

Bases: _ActionsContainer, ArgumentParser


              flowchart TD
              src.qargparse.parser.ArgumentParser[ArgumentParser]
              src.qargparse.parser._ActionsContainer[_ActionsContainer]

                              src.qargparse.parser._ActionsContainer --> src.qargparse.parser.ArgumentParser
                


              click src.qargparse.parser.ArgumentParser href "" "src.qargparse.parser.ArgumentParser"
              click src.qargparse.parser._ActionsContainer href "" "src.qargparse.parser._ActionsContainer"
            

Queue-aware ArgumentParser with task execution support.

This class extends argparse.ArgumentParser with queue-based argument accumulation and task dispatch semantics.

In addition to standard argparse behavior, it:

  • Registers custom queue actions (q, q_true, q_false, task)
  • Tracks queued keyword arguments between task invocations
  • Collects task execution blocks during parsing
  • Removes internal bookkeeping attributes before returning
  • Returns both the cleaned namespace and structured task data

The parser enables task-oriented CLI workflows where parameters are accumulated and executed in ordered blocks.

Source code in src/qargparse/parser.py
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
class ArgumentParser(_ActionsContainer, argparse.ArgumentParser):
    """Queue-aware ArgumentParser with task execution support.

    This class extends ``argparse.ArgumentParser`` with queue-based
    argument accumulation and task dispatch semantics.

    In addition to standard argparse behavior, it:

    - Registers custom queue actions (``q``, ``q_true``, ``q_false``, ``task``)
    - Tracks queued keyword arguments between task invocations
    - Collects task execution blocks during parsing
    - Removes internal bookkeeping attributes before returning
    - Returns both the cleaned namespace and structured task data

    The parser enables task-oriented CLI workflows where parameters
    are accumulated and executed in ordered blocks.
    """

    def parse_args(self, *args, namespace=None, **kwargs) -> Tuple[argparse.Namespace, TasksKwargs]:
        """Parse CLI arguments and return structured task information.

        This method extends the default ``argparse.ArgumentParser.parse_args``
        behavior by:

        1. Initializing internal queue and task storage attributes
           in the parsing namespace.
        2. Parsing arguments using the parent implementation.
        3. Extracting collected task blocks.
        4. Validating that no queued arguments remain unprocessed.
        5. Removing temporary queue-related attributes.
        6. Cleaning queue action destinations from the namespace.
        7. Merging default values across parser and groups.

        Args:
            *args:
                Positional arguments forwarded to
                ``argparse.ArgumentParser.parse_args``.
            namespace (argparse.Namespace, optional):
                Existing namespace to populate. If None, a new
                namespace is created.
            **kwargs:
                Additional keyword arguments forwarded to
                ``parse_args``.

        Returns:
            Tuple[argparse.Namespace, TasksKwargs]:
                - namespace:
                    The parsed namespace with all temporary queue
                    attributes removed.
                - tasks:
                    A ``TasksKwargs`` instance containing:
                        - Ordered task execution blocks
                        - Associated default values

        Raises:
            ValueError:
                If queued keyword arguments remain after parsing,
                indicating that a task trigger was missing.
        """
        if namespace is None:
            namespace = argparse.Namespace()
        setattr(namespace, Q_KWARGS, {})
        setattr(namespace, Q_TASKS, [])
        namespace = super().parse_args(*args, namespace=namespace, **kwargs)
        q_kwargs, q_tasks = (getattr(namespace, Q_KWARGS), getattr(namespace, Q_TASKS))
        delattr(namespace, Q_KWARGS)
        delattr(namespace, Q_TASKS)
        if q_kwargs:
            raise ValueError("The keyword arguments queue is not empty: did you forgot a task call?")
        for q_action in [action for action in self._actions if isinstance(action, Queue)]:
            if q_action.dest in namespace:
                delattr(namespace, q_action.dest)
        _q_defaults = self._q_defaults
        for group in self._action_groups:
            _q_defaults = merge_nested_dict(_q_defaults, group._q_defaults)
        return (namespace, TasksKwargs(tasks=q_tasks, defaults=_q_defaults))

parse_args(*args, namespace=None, **kwargs)

Parse CLI arguments and return structured task information.

This method extends the default argparse.ArgumentParser.parse_args behavior by:

  1. Initializing internal queue and task storage attributes in the parsing namespace.
  2. Parsing arguments using the parent implementation.
  3. Extracting collected task blocks.
  4. Validating that no queued arguments remain unprocessed.
  5. Removing temporary queue-related attributes.
  6. Cleaning queue action destinations from the namespace.
  7. Merging default values across parser and groups.

Parameters:

Name Type Description Default
*args

Positional arguments forwarded to argparse.ArgumentParser.parse_args.

()
namespace Namespace

Existing namespace to populate. If None, a new namespace is created.

None
**kwargs

Additional keyword arguments forwarded to parse_args.

{}

Returns:

Type Description
Tuple[Namespace, TasksKwargs]

Tuple[argparse.Namespace, TasksKwargs]: - namespace: The parsed namespace with all temporary queue attributes removed. - tasks: A TasksKwargs instance containing: - Ordered task execution blocks - Associated default values

Raises:

Type Description
ValueError

If queued keyword arguments remain after parsing, indicating that a task trigger was missing.

Source code in src/qargparse/parser.py
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
def parse_args(self, *args, namespace=None, **kwargs) -> Tuple[argparse.Namespace, TasksKwargs]:
    """Parse CLI arguments and return structured task information.

    This method extends the default ``argparse.ArgumentParser.parse_args``
    behavior by:

    1. Initializing internal queue and task storage attributes
       in the parsing namespace.
    2. Parsing arguments using the parent implementation.
    3. Extracting collected task blocks.
    4. Validating that no queued arguments remain unprocessed.
    5. Removing temporary queue-related attributes.
    6. Cleaning queue action destinations from the namespace.
    7. Merging default values across parser and groups.

    Args:
        *args:
            Positional arguments forwarded to
            ``argparse.ArgumentParser.parse_args``.
        namespace (argparse.Namespace, optional):
            Existing namespace to populate. If None, a new
            namespace is created.
        **kwargs:
            Additional keyword arguments forwarded to
            ``parse_args``.

    Returns:
        Tuple[argparse.Namespace, TasksKwargs]:
            - namespace:
                The parsed namespace with all temporary queue
                attributes removed.
            - tasks:
                A ``TasksKwargs`` instance containing:
                    - Ordered task execution blocks
                    - Associated default values

    Raises:
        ValueError:
            If queued keyword arguments remain after parsing,
            indicating that a task trigger was missing.
    """
    if namespace is None:
        namespace = argparse.Namespace()
    setattr(namespace, Q_KWARGS, {})
    setattr(namespace, Q_TASKS, [])
    namespace = super().parse_args(*args, namespace=namespace, **kwargs)
    q_kwargs, q_tasks = (getattr(namespace, Q_KWARGS), getattr(namespace, Q_TASKS))
    delattr(namespace, Q_KWARGS)
    delattr(namespace, Q_TASKS)
    if q_kwargs:
        raise ValueError("The keyword arguments queue is not empty: did you forgot a task call?")
    for q_action in [action for action in self._actions if isinstance(action, Queue)]:
        if q_action.dest in namespace:
            delattr(namespace, q_action.dest)
    _q_defaults = self._q_defaults
    for group in self._action_groups:
        _q_defaults = merge_nested_dict(_q_defaults, group._q_defaults)
    return (namespace, TasksKwargs(tasks=q_tasks, defaults=_q_defaults))

__init__(*args, **kwargs)

Initialize the custom _ActionsContainer and register queue actions and cutsom type.

Parameters:

Name Type Description Default
*args

Positional arguments forwarded to argparse._ActionsContainer.

()
**kwargs

Keyword arguments forwarded to argparse._ActionsContainer.

{}
Source code in src/qargparse/parser.py
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def __init__(self, *args, **kwargs):
    """Initialize the custom _ActionsContainer and register queue actions
    and cutsom type.

    Args:
        *args: Positional arguments forwarded to argparse._ActionsContainer.
        **kwargs: Keyword arguments forwarded to argparse._ActionsContainer.
    """
    super().__init__(*args, **kwargs)

    # Defaults for q actions
    self._q_defaults = {} # d[dest][alias] = default

    # Register custom queue actions
    self.register("action", ACTION_Q, Queue)
    self.register("action", ACTION_Q_TRUE, QueueTrue)
    self.register("action", ACTION_Q_FALSE, QueueFalse)
    self.register("action", ACTION_TASK, Task)

    # Register custom type
    self.register("type", TYPE_KWARGS, type_kwargs)
    self.register("type", TYPE_ARGS, type_args)

add_argument(*args, action='store', dest=None, default=..., alias='', **kwargs)

Add an argument with extended queue and alias support.

This method extends argparse._ActionsContainer.add_argument by:

  • Supporting custom queue-based actions (q, q_true, q_false, task).
  • Allowing alias-based parameter mapping for queue actions.
  • Tracking per-destination default values for queued arguments.

When using the q action, an optional alias may be provided to associate a task-specific default value with a parameter. Aliases are internally prefixed to distinguish them at parse time.

Parameters:

Name Type Description Default
*args

Positional arguments forwarded to argparse.add_argument. For queue actions with alias, the first element must be a single string option.

()
action str

The action type. Defaults to "store".

'store'
dest str

Explicit destination name. If omitted for optional arguments, it is inferred automatically.

None
default Any

Default value for the argument. For queue actions, defaults may be stored internally per alias.

...
alias str

Optional alias name associated with the parameter. Only valid when action == ACTION_Q.

''
**kwargs

Additional keyword arguments forwarded to argparse.

{}

Returns:

Type Description
Action

argparse.Action: The created action object.

Raises:

Type Description
TypeError

If alias is not a string.

ValueError

If alias is used with a non-queue action, if multiple string options are provided with alias, or if a duplicate alias is registered.

Source code in src/qargparse/parser.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
def add_argument(self, 
                 *args, 
                 action: str='store', 
                 dest=None, default=..., 
                 alias: str="", 
                 **kwargs) -> argparse.Action:
    """Add an argument with extended queue and alias support.

    This method extends ``argparse._ActionsContainer.add_argument`` by:

    - Supporting custom queue-based actions (``q``, ``q_true``,
      ``q_false``, ``task``).
    - Allowing alias-based parameter mapping for queue actions.
    - Tracking per-destination default values for queued arguments.

    When using the ``q`` action, an optional ``alias`` may be provided
    to associate a task-specific default value with a parameter.
    Aliases are internally prefixed to distinguish them at parse time.

    Args:
        *args:
            Positional arguments forwarded to ``argparse.add_argument``.
            For queue actions with alias, the first element must be
            a single string option.
        action (str, optional):
            The action type. Defaults to ``"store"``.
        dest (str, optional):
            Explicit destination name. If omitted for optional
            arguments, it is inferred automatically.
        default (Any, optional):
            Default value for the argument. For queue actions,
            defaults may be stored internally per alias.
        alias (str, optional):
            Optional alias name associated with the parameter.
            Only valid when ``action == ACTION_Q``.
        **kwargs:
            Additional keyword arguments forwarded to argparse.

    Returns:
        argparse.Action:
            The created action object.

    Raises:
        TypeError:
            If ``alias`` is not a string.
        ValueError:
            If alias is used with a non-queue action, if multiple
            string options are provided with alias, or if a duplicate
            alias is registered.
    """
    if not isinstance(alias, str):
        raise TypeError("Parameter 'alias' must be a string!")
    if alias and action != ACTION_Q:
        raise ValueError(f"Parameter 'alias' can only be set with a '{ACTION_Q}' action!")
    if action == ACTION_Q:
        string_options = args[0]
        args = args[1:]
        # Check string options
        #  - Must be str or 1 element list
        if not isinstance(string_options, str):
            if not isinstance(string_options, list) or len(string_options) != 1:
                raise ValueError("Can not set an alias with more than 1 string option!")
            string_options = string_options[0]
        # Set dest
        #  Dest must be set to add elements to self._q_defaults
        if dest is None:
            dest = self._get_optional_kwargs(string_options, *args, **kwargs)['dest']
        # Prepare _q_defaults dict
        if alias or default is not ...:
            if dest not in self._q_defaults:
                self._q_defaults[dest] = {}
        if alias:
            # 1. Try to add the parameter, without default, if it was not added before
            try:
                super().add_argument(string_options, *args, action=action, dest=dest, default=..., **kwargs)
            except argparse.ArgumentError: # The argument was already present
                pass
            # 2. Update aliases
            #  Only if a default value is set
            if alias in self._q_defaults[dest]:
                raise ValueError("An alias already exist for this destination!")
            if default is not ...:
                self._q_defaults[dest][alias] = default
            # 3. Set string option name
            #  Add the alias to the string option
            string_options = f"{F_ALIAS_PREFIX.format(alias)}{string_options}"
        elif default is not ...:
            # No alias, but a q action with a default
            #  -> We must save the default
            self._q_defaults[dest][alias] = default
        # Rebuilt args
        args = (string_options,) + args
    # Reset the default default value if necessary
    default = None if default is ... else default
    return super().add_argument(*args, action=action, dest=dest, default=default, **kwargs)

add_arguments(regular=[], q_global=[], tasks={}, task_prefix='--', alias=..., verbose=False, _parser_name='parser')

Add multiple arguments using structured task definitions.

This high-level helper allows defining:

  • Regular argparse arguments
  • Global queue arguments shared across tasks
  • Task-specific argument groups
  • Task launch triggers

Arguments are added in the following order:

  1. regular arguments (standard argparse actions)
  2. q_global arguments (shared queue actions)
  3. Task-specific argument groups and their parameters
  4. Task trigger arguments (ACTION_TASK)

Parameters:

Name Type Description Default
regular List[Tuple[Union[str, List[str]], Dict[str, Any]]]

List of tuples (args, kwargs) passed to add_argument. Must contain only standard (non-queue) argparse actions.

[]
q_global List[Union[Tuple[Union[str, List[str]], Dict[str, Any]], Tuple[Union[str, List[str]], Dict[str, Any], Dict[str, Any]]]]

List of tuples defining shared queue arguments. Each element may be:

  • (args, kwargs)
  • (args, kwargs, task_defaults)

where task_defaults maps task names to task-specific default overrides.

[]
tasks Dict[str, Union[List[Tuple[Union[str, List[str]], Dict[str, Any]]], Tuple[List[Tuple[Union[str, List[str]], Dict[str, Any]]], Dict[str, Any]]]]

Mapping of task name to either:

  • A list of (args, kwargs) queue arguments.
  • A tuple (arguments, group_kwargs) where arguments is a list of (args, kwargs) queue arguments and group_kwargs are passed to add_argument_group.
{}
task_prefix str

Prefix used for task trigger arguments (default: "--").

'--'
alias str

Optional alias automatically applied to all queue arguments.

...
verbose bool

If True, prints generated parser-building code.

False
_parser_name str

Internal name used when printing verbose output.

'parser'

Raises:

Type Description
TypeError

If q_global elements are not tuples.

ValueError

If invalid action types are used or if a task referenced in q_global is not defined in tasks.

Source code in src/qargparse/parser.py
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
def add_arguments(
    self,
    regular: List[Tuple[Union[str, List[str]], Dict[str, Any]]] = [],
    q_global: List[
        Union[
            Tuple[Union[str, List[str]], Dict[str, Any]],
            Tuple[Union[str, List[str]], Dict[str, Any], Dict[str, Any]]
        ]
    ] = [],
    tasks: Dict[
        str,
        Union[
            List[Tuple[Union[str, List[str]], Dict[str, Any]]],
            Tuple[
                List[Tuple[Union[str, List[str]], Dict[str, Any]]],
                Dict[str, Any]
            ]
        ]
    ] = {},
    task_prefix: str = "--",
    alias: str = ...,
    verbose: bool = False,
    _parser_name: str = "parser"
) -> None:
    """Add multiple arguments using structured task definitions.

    This high-level helper allows defining:

    - Regular argparse arguments
    - Global queue arguments shared across tasks
    - Task-specific argument groups
    - Task launch triggers

    Arguments are added in the following order:

    1. ``regular`` arguments (standard argparse actions)
    2. ``q_global`` arguments (shared queue actions)
    3. Task-specific argument groups and their parameters
    4. Task trigger arguments (``ACTION_TASK``)

    Args:
        regular:
            List of tuples ``(args, kwargs)`` passed to
            ``add_argument``. Must contain only standard
            (non-queue) argparse actions.
        q_global:
            List of tuples defining shared queue arguments.
            Each element may be:

            - ``(args, kwargs)``
            - ``(args, kwargs, task_defaults)``

            where ``task_defaults`` maps task names to
            task-specific default overrides.
        tasks:
            Mapping of task name to either:

            - A list of ``(args, kwargs)`` queue arguments.
            - A tuple ``(arguments, group_kwargs)`` where
              ``arguments`` is a list of ``(args, kwargs)`` queue
              arguments and ``group_kwargs`` are passed to 
              ``add_argument_group``.
        task_prefix:
            Prefix used for task trigger arguments (default: "--").
        alias:
            Optional alias automatically applied to all
            queue arguments.
        verbose:
            If True, prints generated parser-building code.
        _parser_name:
            Internal name used when printing verbose output.

    Raises:
        TypeError:
            If ``q_global`` elements are not tuples.
        ValueError:
            If invalid action types are used or if a task
            referenced in ``q_global`` is not defined in ``tasks``.
    """
    all_task_kwargs = {} # d[task][parameter] = default_value
    if verbose and _parser_name=="parser":
        print("from qargparse import ArgumentParser\n")
        print(f"{_parser_name} = ArgumentParser()\n")
    for args, kwargs in regular:
        if not isinstance(args, tuple):
            args = (args,)
        if 'action' in kwargs and kwargs['action'] in Q_ACTIONS+[ACTION_TASK]:
            raise ValueError("Parameter 'regular' can only contain non-Queue actions!")
        if verbose:
            print(f"{_parser_name}.add_argument({args_to_str(args)}, {kwargs_to_str(kwargs)})")
        self.add_argument(*args, **kwargs)
    if verbose and regular and q_global:
            print("")
    for element in q_global:
        if not isinstance(element, tuple):
            raise TypeError("Parameter 'q_global' must be a list of tuple!")
        if len(element) == 2:
            args, kwargs = element
            task_kwargs = {}
        elif len(element) == 3:
            args, kwargs, task_kwargs = element
        if not isinstance(args, tuple):
            args = (args,)
        if 'action' not in kwargs:
            kwargs['action'] = ACTION_Q
        elif kwargs['action'] not in Q_ACTIONS:
            raise ValueError("Parameter 'q_global' can only contain Queue actions!")
        if alias is not ...:
            kwargs['alias'] = alias
        if verbose:
            print(f"{_parser_name}.add_argument({args_to_str(args)}, {kwargs_to_str(kwargs)})")
        self.add_argument(*args, **kwargs)
        # Save the parameter to add task-specific arguments
        for task, kwargs in task_kwargs.items():
            if task not in all_task_kwargs:
                all_task_kwargs[task] = {}
            all_task_kwargs[task][args[0]] = kwargs
    for task, tuple_or_list in tasks.items():
        if not isinstance(tuple_or_list, tuple):
            tuple_or_list = (tuple_or_list, dict(title=task.replace("_", " ").title(), description=f"Specific parameters of: {task}()"))
        l_add_parameter, kwargs_add_parameter_group = tuple_or_list
        _parser_grp_name = f"PARSER_TASK_{task.upper()}"
        if verbose:
            print(f"\n{_parser_grp_name} = {_parser_name}.add_argument_group({kwargs_to_str(kwargs_add_parameter_group)})")
        group = self.add_argument_group(**kwargs_add_parameter_group)
        group.add_arguments(q_global=l_add_parameter, verbose=verbose, _parser_name=_parser_grp_name)
        if task in all_task_kwargs:
            task_kwargs = all_task_kwargs.pop(task)
            for task_arg, kwargs in task_kwargs.items():
                group.add_arguments(q_global=[(task_arg, kwargs)], alias=task, verbose=verbose, _parser_name=_parser_grp_name)
        args = (f"{task_prefix}{task}",)
        kwargs = dict(dest=task, action=ACTION_TASK, help=f"Launch '{task}' task.")
        if verbose:
            print(f"{_parser_grp_name}.add_argument({args_to_str(args)}, {kwargs_to_str(kwargs)})")
        group.add_argument(*args, **kwargs)
    if all_task_kwargs:
        raise ValueError(f"Missing tasks definition: {", ".join(all_task_kwargs.keys())}")

add_argument_group(*args, **kwargs)

Create and register a custom argument group.

This method overrides the base implementation to return a specialized _ArgumentGroup instance that preserves queue-aware behavior.

Parameters:

Name Type Description Default
*args

Positional arguments forwarded to argparse._ActionsContainer.add_argument_group.

()
**kwargs

Keyword arguments forwarded to the group constructor.

{}

Returns:

Name Type Description
_ArgumentGroup

The created argument group instance.

Source code in src/qargparse/parser.py
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
def add_argument_group(self, *args, **kwargs):
    """Create and register a custom argument group.

    This method overrides the base implementation to return a
    specialized ``_ArgumentGroup`` instance that preserves
    queue-aware behavior.

    Args:
        *args:
            Positional arguments forwarded to
            ``argparse._ActionsContainer.add_argument_group``.
        **kwargs:
            Keyword arguments forwarded to the group constructor.

    Returns:
        _ArgumentGroup:
            The created argument group instance.
    """
    group = _ArgumentGroup(self, *args, **kwargs)
    self._action_groups.append(group)
    return group