From 0407215530c849985b6d1b2be5f16cc8f4b1ae02 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sun, 23 Aug 2026 14:06:01 +0200 Subject: [PATCH] init.detect_modules(): Add base_types filter Add a parameter "base_types" to detect_modules(), defaulting to None. If it is not None, a module is only exported if its same-named object inherits from one of the given types. Modules without a same-named class are skipped instead of raising AttributeError, which covers helper modules. The return annotation becomes Sequence[str] instead of list[str] to remove mutability for easier type checking. 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/init.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/python/jw/pkg/lib/init.py b/src/python/jw/pkg/lib/init.py index 8098f687..014bdaed 100644 --- a/src/python/jw/pkg/lib/init.py +++ b/src/python/jw/pkg/lib/init.py @@ -6,16 +6,17 @@ from importlib import import_module from typing import TYPE_CHECKING if TYPE_CHECKING: - from collections.abc import MutableMapping - from typing import Any + from collections.abc import Iterable, MutableMapping + from typing import Any, Sequence def detect_modules( namespace: MutableMapping[str, Any], prefix: str | None = None, skip: set[str] | None = None, *, + base_types: Iterable[type[Any]] | None = None, extend_namespace: bool = True, -) -> list[str]: +) -> Sequence[str]: package_name = namespace.get("__name__") package_path = namespace.get("__path__") @@ -41,7 +42,11 @@ def detect_modules( continue module = import_module(f".{module_name}", package_name) - cls = getattr(module, module_name) + cls = getattr(module, module_name, None) + if cls is None or not isinstance(cls, type): + continue + if base_types is not None and not issubclass(cls, tuple(base_types)): + continue namespace[module_name] = cls ret.append(module_name) -- 2.55.0