From 75b6603a3f5029915dd312eadead930e99ff03d9 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sat, 15 Aug 2026 00:05:23 +0200 Subject: [PATCH] lib.Cmd: Add single Cmd to add_subcommands() add_subcommands() advertises Cmd and list[Cmd] in its signature, but a single Cmd instance raises NotImplementedError, and since the list branch handles every element through the same method, a list of Cmd instances is broken as well. The only working forms are Types and lists of Types. Handle a single Cmd instance by reparenting it to the caller and appending it to the children, tracking its class like the class-based path does. Instances whose name is already taken by a child are rejected, mirroring the duplicate-class handling, because argparse cannot register two subparsers under the same name. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.84.2 Signed-off-by: Jan Lindemann --- src/python/jw/pkg/lib/Cmd.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/python/jw/pkg/lib/Cmd.py b/src/python/jw/pkg/lib/Cmd.py index 51fea68f..dc7147ad 100644 --- a/src/python/jw/pkg/lib/Cmd.py +++ b/src/python/jw/pkg/lib/Cmd.py @@ -88,7 +88,15 @@ class AbstractCmd(abc.ABC): self, cmds: Cmd | list[Cmd] | Types[Any] | list[Types[Any]] ) -> None: if isinstance(cmds, Cmd): - raise NotImplementedError('Single Cmd should be handled elsewhere') + if any(child.name == cmds.name for child in self.__children): + raise Exception( + f'Can\'t register subcommand with already taken name "{cmds.name}"' + ) + self.__child_classes.append(type(cmds)) + cmds.set_parent(self) + self.__children.append(cmds) + assert len(self.__children) == len(self.__child_classes) + return if isinstance(cmds, list): for cmd in cmds: self.add_subcommands(cmd)