File: cmdloader.py

package info (click to toggle)
python-nubia 0.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 772 kB
  • sloc: python: 4,182; makefile: 9; sh: 1
file content (45 lines) | stat: -rw-r--r-- 1,435 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
#
from importlib import import_module
import pkgutil
import types
import typing as t


def _walk_module(module: types.ModuleType):
    for attr_name in dir(module):
        # filter out private members
        if not attr_name.startswith("_"):
            member = getattr(module, attr_name)
            if hasattr(member, "__command"):
                yield member


def _walk_package(name, path) -> t.List[types.FunctionType]:
    packages = pkgutil.walk_packages(path, prefix=f"{name}.")
    for importer, modname, ispkg in packages:
        loaded = import_module(modname)
        if not ispkg:
            yield from _walk_module(loaded)


def load_commands(base_package) -> None:
    """
    Loads all commands defined in a loaded python package object. This function
    recursively look for classes and function annotated with @command and return
    a list of these objects.
    """
    if base_package is not None:
        path = None
        if hasattr(base_package, "__path__"):
            path = getattr(base_package, "__path__")
        else:
            path = getattr(base_package, "__file__")
        assert path is not None
        yield from _walk_package(base_package.__name__, path)