module_discovery_utils/module_discovery_utils.py
def load_all_modules_in_packages(package_or_set_of_packages):
    """
    Recursively loads all modules from a package object, or set of package objects

    :param package_or_set_of_packages: package object, or iterable of package objects
    :return: list of all unique modules discovered by the function
    """
    if isinstance(package_or_set_of_packages, types.ModuleType):
        packages = [package_or_set_of_packages]
    elif isinstance(package_or_set_of_packages, Iterable) and not isinstance(package_or_set_of_packages, (dict, str)):
        packages = package_or_set_of_packages
    else:
        raise Exception("This function only accepts a module reference, or an iterable of said objects")

    imported = packages.copy()

    for package in packages:
        if not hasattr(package, '__path__'):
            raise Exception(
                'Package object passed in has no __path__ attribute. '
                'Make sure to pass in imported references to the packages in question.'
            )

        for module_finder, name, ispkg in pkgutil.walk_packages(package.__path__):
            module_name = '{}.{}'.format(package.__name__, name)
            current_module = importlib.import_module(module_name)
            imported.append(current_module)
            if ispkg:
                imported += load_all_modules_in_packages(current_module)

    for module in imported:
        # This is to cover cases where simply importing a module doesn't execute all the code/definitions within
        # I don't totally understand the reasons for this, but I do know enumerating a module's context (like with dir)
        # seems to solve things
        dir(module)

    return list(
        {
            module.__name__: module

            for module in imported
        }.values()
    )
def load_all_modules_in_packages(package_or_set_of_packages):
    if isinstance(package_or_set_of_packages, types.ModuleType):
        packages = [package_or_set_of_packages]
    elif isinstance(package_or_set_of_packages, Iterable) and not isinstance(package_or_set_of_packages, (dict, str)):
        packages = package_or_set_of_packages
    else:
        raise Exception("This function only accepts a module reference, or an iterable of said objects")

    imported = packages.copy()

    for package in packages:
        if not hasattr(package, '__path__'):
            raise Exception(
                'Package object passed in has no __path__ attribute. '
                'Make sure to pass in imported references to the packages in question.'
            )

        for module_finder, name, ispkg in pkgutil.walk_packages(package.__path__):
            module_name = '{}.{}'.format(package.__name__, name)
            current_module = importlib.import_module(module_name)
            imported.append(current_module)
            if ispkg:
                imported += load_all_modules_in_packages(current_module)

    for module in imported:
        # This is to cover cases where simply importing a module doesn't execute all the code/definitions within
        # I don't totally understand the reasons for this, but I do know enumerating a module's context (like with dir)
        # seems to solve things
        dir(module)

    return list(
        {
            module.__name__: module

            for module in imported
        }.values()
    )
def load_all_modules_in_packages ( package_or_set_of_packages ) : if isinstance ( package_or_set_of_packages , types . ModuleType ) : packages = [ package_or_set_of_packages ] elif isinstance ( package_or_set_of_packages , Iterable ) and not isinstance ( package_or_set_of_packages , ( dict , str ) ) : packages = package_or_set_of_packages else : raise Exception ( "This function only accepts a module reference, or an iterable of said objects" ) imported = packages . copy ( ) for package in packages : if not hasattr ( package , '__path__' ) : raise Exception ( 'Package object passed in has no __path__ attribute. ' 'Make sure to pass in imported references to the packages in question.' ) for module_finder , name , ispkg in pkgutil . walk_packages ( package . __path__ ) : module_name = '{}.{}' . format ( package . __name__ , name ) current_module = importlib . import_module ( module_name ) imported . append ( current_module ) if ispkg : imported += load_all_modules_in_packages ( current_module ) for module in imported : # This is to cover cases where simply importing a module doesn't execute all the code/definitions within # I don't totally understand the reasons for this, but I do know enumerating a module's context (like with dir) # seems to solve things dir ( module ) return list ( { module . __name__ : module for module in imported } . values ( ) )
Recursively loads all modules from a package object, or set of package objects

    :param package_or_set_of_packages: package object, or iterable of package objects
    :return: list of all unique modules discovered by the function
Recursively loads all modules from a package object or set of package objects