From 13ec34cc5779967be64526e0ebbda1f557d78cf4 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sat, 30 May 2026 12:44:55 +0200 Subject: [PATCH] lib.init.detect_modules(): Add function Not all __init__.py modules are generated by python-tools.sh, some are needed early to make jw-pkg useful without generation, notably in jw.pkg.cmds. Add detect_modules() to unify that detection, and place it into a minimal module lib.init to not increase startup time cost. Signed-off-by: Jan Lindemann --- src/python/jw/pkg/cmds/__init__.py | 20 +++++------- src/python/jw/pkg/cmds/pkg/__init__.py | 18 +++++------ src/python/jw/pkg/cmds/platform/__init__.py | 18 +++++------ src/python/jw/pkg/cmds/projects/__init__.py | 18 +++++------ src/python/jw/pkg/lib/init.py | 36 +++++++++++++++++++++ 5 files changed, 68 insertions(+), 42 deletions(-) create mode 100644 src/python/jw/pkg/lib/init.py diff --git a/src/python/jw/pkg/cmds/__init__.py b/src/python/jw/pkg/cmds/__init__.py index 409b58b9..1fed7a71 100644 --- a/src/python/jw/pkg/cmds/__init__.py +++ b/src/python/jw/pkg/cmds/__init__.py @@ -1,13 +1,9 @@ -import importlib, pkgutil +from ..lib.init import detect_modules -__all__ = [] - -for finder, module_name, ispkg in pkgutil.iter_modules(__path__): - if not module_name.startswith("Cmd"): - continue - if module_name == "Cmd": - continue - module = importlib.import_module(f".{module_name}", __name__) - cls = getattr(module, module_name) - globals()[module_name] = cls - __all__.append(module_name) +__all__ = detect_modules( + package_name = __name__, + package_path = __path__, + namespace = globals(), + prefix = "Cmd", + skip = {"Cmd"}, +) # pyright: ignore[reportUnsupportedDunderAll] diff --git a/src/python/jw/pkg/cmds/pkg/__init__.py b/src/python/jw/pkg/cmds/pkg/__init__.py index 7837b8d7..475565ba 100644 --- a/src/python/jw/pkg/cmds/pkg/__init__.py +++ b/src/python/jw/pkg/cmds/pkg/__init__.py @@ -1,11 +1,9 @@ -import importlib, pkgutil +from ...lib.init import detect_modules -__all__ = [] - -for finder, module_name, ispkg in pkgutil.iter_modules(__path__): - if not module_name.startswith("Cmd"): - continue - module = importlib.import_module(f".{module_name}", __name__) - cls = getattr(module, module_name) - globals()[module_name] = cls - __all__.append(module_name) +__all__ = detect_modules( + package_name = __name__, + package_path = __path__, + namespace = globals(), + prefix = "Cmd", + skip = {"Cmd"}, +) # pyright: ignore[reportUnsupportedDunderAll] diff --git a/src/python/jw/pkg/cmds/platform/__init__.py b/src/python/jw/pkg/cmds/platform/__init__.py index 7837b8d7..475565ba 100644 --- a/src/python/jw/pkg/cmds/platform/__init__.py +++ b/src/python/jw/pkg/cmds/platform/__init__.py @@ -1,11 +1,9 @@ -import importlib, pkgutil +from ...lib.init import detect_modules -__all__ = [] - -for finder, module_name, ispkg in pkgutil.iter_modules(__path__): - if not module_name.startswith("Cmd"): - continue - module = importlib.import_module(f".{module_name}", __name__) - cls = getattr(module, module_name) - globals()[module_name] = cls - __all__.append(module_name) +__all__ = detect_modules( + package_name = __name__, + package_path = __path__, + namespace = globals(), + prefix = "Cmd", + skip = {"Cmd"}, +) # pyright: ignore[reportUnsupportedDunderAll] diff --git a/src/python/jw/pkg/cmds/projects/__init__.py b/src/python/jw/pkg/cmds/projects/__init__.py index 7837b8d7..475565ba 100644 --- a/src/python/jw/pkg/cmds/projects/__init__.py +++ b/src/python/jw/pkg/cmds/projects/__init__.py @@ -1,11 +1,9 @@ -import importlib, pkgutil +from ...lib.init import detect_modules -__all__ = [] - -for finder, module_name, ispkg in pkgutil.iter_modules(__path__): - if not module_name.startswith("Cmd"): - continue - module = importlib.import_module(f".{module_name}", __name__) - cls = getattr(module, module_name) - globals()[module_name] = cls - __all__.append(module_name) +__all__ = detect_modules( + package_name = __name__, + package_path = __path__, + namespace = globals(), + prefix = "Cmd", + skip = {"Cmd"}, +) # pyright: ignore[reportUnsupportedDunderAll] diff --git a/src/python/jw/pkg/lib/init.py b/src/python/jw/pkg/lib/init.py new file mode 100644 index 00000000..74e14449 --- /dev/null +++ b/src/python/jw/pkg/lib/init.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from collections.abc import MutableMapping + from typing import Any, Iterable + +def detect_modules( + package_name: str, + package_path: Iterable[str], + namespace: MutableMapping[str, Any], + prefix: str, + skip: set[str] | None = None, +) -> list[str]: + + import importlib + import pkgutil + + ret: list[str] = [] + skip = skip or set() + + for _finder, module_name, _ispkg in pkgutil.iter_modules(package_path): + if not module_name.startswith(prefix): + continue + + if module_name in skip: + continue + + module = importlib.import_module(f'.{module_name}', package_name) + cls = getattr(module, module_name) + + namespace[module_name] = cls + ret.append(module_name) + + return ret