namespaces
link: https://packaging.python.org/en/latest/guides/packaging-namespace-packages/
ΠΡΠΈΠΌΠ΅Ρ Native namespace packages:
mynamespace-subpackage-a/
    pyproject.toml # AND/OR setup.py, setup.cfg
    src/
        mynamespace/ # namespace package
            # No __init__.py here.
            subpackage_a/
                # Regular import packages have an __init__.py.
                __init__.py
                module.pyΠ Π² pyproject.toml:
[build-system]
...
[tool.setuptools.packages.find]
where = ["src/"]
include = ["mynamespace.subpackage_a"]
[project]
name = "mynamespace-subpackage-a"
...ΠΠΎΠΈΡΠΊ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ΄:
import importlib
import inspect
import pkgutil
import types
import typing
import ikemurami.plugin
from ikemurami.core import Plugin
def iter_namespace(ns_pkg):
    return pkgutil.iter_modules(ns_pkg.__path__, ns_pkg.__name__ + '.')
def get_plugins(module: types.ModuleType) -> typing.List[Plugin]:
    plugins: typing.List[Plugin] = list()
    for attr_name in dir(module):
        attr = getattr(module, attr_name)
        if inspect.isclass(attr) and issubclass(attr, Plugin):
            plugins.append(attr)
    return plugins
def main():
    discovered_plugins: typing.List[Plugin] = sum(
        [
            get_plugins(importlib.import_module(name))
            for finder, name, ispkg
            in iter_namespace(ikemurami.plugin)
        ],
        []
    )
    print(discovered_plugins)
    for plugin in discovered_plugins:
        print('Plugin', plugin, plugin.run(3, 5))
if __name__ == '__main__':
    main()
Plugin base class:
class Plugin:
    @staticmethod
    def run(a: int, b: int) -> int:
        ...
Plugin class:
from ikemurami.core import Plugin
class MyPlugin(Plugin):
    def run(a: int, b: int) -> int:
        return a * b
Last updated