lib.Cmd.load_subcommands(): Add method

Push cmds.Cmd._add_subcommands() as lib.Cmd.load_subcommands() one step up to the top of the type hierarchy ladder.

By default, it does the same thing, i.e. load subcommands matching frobnicate.Cmd* if called on class CmdFrobnicate.

This commit also replaces invocations of Cmd._add_subcommands() by invocations of this new method.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-05-01 10:17:24 +02:00
commit 7e2099877c
Signed by: Jan Lindemann
GPG key ID: 3750640C9E25DD61
8 changed files with 16 additions and 14 deletions

View file

@ -8,7 +8,7 @@ import inspect, sys, re, abc, argparse
from argparse import ArgumentParser, _SubParsersAction
from .log import *
from .Types import Types
from .Types import Types, LoadTypes
class Cmd(abc.ABC): # export
@ -106,6 +106,15 @@ class Cmd(abc.ABC): # export
return
raise Exception(f'Tried to add sub-commands of unknown type {type(cmds)}')
def load_subcommands(self, modules: str|list[str]|None=None, name_filter: str=r'Cmd[^.]') -> None:
if modules is None:
# Derive module search path for the calling module's subcommands
# from the module path of the calling module itself
modules = [type(self).__module__.replace('Cmd', '').lower()]
elif isinstance(modules, str):
modules = [modules]
self.add_subcommands(LoadTypes(modules, type_name_filter=name_filter))
# To be overridden by derived class in case the command does take arguments.
# Will be called from App base class constructor and set up the parser hierarchy
def add_arguments(self, parser: ArgumentParser) -> None: