nubia/internal/cmdloader.py (24 lines of code) (raw):

#!/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. # 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 = importer.find_module(modname).load_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)