Last active
April 30, 2020 21:26
-
-
Save tombulled/5115d241164f7ed9e351db1a67e258d8 to your computer and use it in GitHub Desktop.
Python3: Automatically attempt to import relative modules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Module containing the utility function: include | |
''' | |
import pkgutil | |
import importlib | |
import sys | |
from typing import Callable | |
from _frozen_importlib import ModuleSpec | |
def include(spec: ModuleSpec, func: Callable = None) -> dict: | |
''' | |
Include relative libraries, or an object they contain. | |
If a relative library exists with an object of the same name inside, | |
it returns that object, otherwise, it returns the library. Libraries | |
or objects are only returned if func(module_name) is true. | |
Args: | |
spec: The specification of the module to import from | |
Example: utils.__spec__ | |
func: A function to filter items by | |
Example: lambda module_name: module_name.endswith('.foo') | |
Returns: | |
A dictionary of imported libraries or objects | |
Example: | |
Package named utils containing foo.py, with a function inside named foo: | |
>>> include(utils.__spec__) | |
{'foo': <function foo at 0x0000027A533CE790>} | |
>>> | |
Package named utils containing foo.py with a function inside named bar: | |
>>> include(utils.__spec__) | |
<module 'utils.foo' from '/path/to/utils/foo.py'> | |
>>> | |
''' | |
if not func: | |
func = lambda module_name: True | |
importlib.util.module_from_spec(spec) | |
module = sys.modules[spec.name] | |
sub_modules = pkgutil.iter_modules(spec.submodule_search_locations) | |
imported = {} | |
for sub_module in sub_modules: | |
sub_module_name = sub_module.name | |
if not func(sub_module_name): continue | |
sub_module = importlib.import_module \ | |
( | |
name = f'.{sub_module_name}', | |
package = spec.name, | |
) | |
object = getattr(sub_module, sub_module_name, None) or sub_module | |
setattr(module, sub_module_name, object) | |
imported[sub_module_name] = object | |
return imported |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment