Skip to content

Presets

duho.presets

Pre-configured argument classes for common patterns.

__all__ = ['LoggingArgs'] module-attribute

LoggingArgs(**kwargs)

Bases: Args

Args subclass with built-in --verbose and --loglevel support.

LoggingArgs is a data mixin (verbosity fields + _set_loglevels_ + the _logger_ property); it defines no __call__ and is NOT itself runnable. Since Plan 13's Args/Cmd split, combine it with Cmd to get a runnable command with logging::

class MyApp(LoggingArgs, Cmd):
    _version_ = "1.2.3"

    def __call__(self):
        self._logger_.info("running")
        return 0

Recommended base order: (LoggingArgs, Cmd) -- data mixin first, executable base last (reads "add logging to a command"). Both orders resolve correctly because LoggingArgs overrides no Cmd member; _logger_/_set_loglevels_ come from LoggingArgs and __call__ from Cmd regardless of order.

Set a class attr _version_ to opt into a --version flag; no separate preset class is needed. --version prints "%(prog)s 1.2.3" and exits 0. It is skipped if a version-dest action already exists (e.g. supplied by a parent parser).

Source code in src/duho/args.py
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
def __init__(self, **kwargs):
    # Namespace.__init__ only setattrs what's passed, so a directly-built
    # instance (or the self-cloning `type(self)(**self._get_kwargs())`
    # pattern) would be missing any declared field not supplied -- notably
    # `store_true` bools, whose default only materializes via argparse.
    # Seed each declared field to its effective default when absent, so a
    # direct instance has the same attribute surface as a parsed one. Only
    # GAPS are filled: passed kwargs (incl. parsed values) always win, and a
    # required field with no default (NOT_DEFINED) is left unset.
    super().__init__(**kwargs)
    for builder in type(self)._getargs_():
        name = builder.name
        if name in kwargs or hasattr(self, name):
            continue
        default = builder._effective_default_()
        if default is not NOT_DEFINED:
            setattr(self, name, default)

loglevels = {} class-attribute instance-attribute

Log Levels

quiet = 0 class-attribute instance-attribute

Quiet level

verbose = 0 class-attribute instance-attribute

Verbose level