Last active
June 10, 2021 02:05
-
-
Save matutter/81159a0f271db4302f5330cd91f93ea5 to your computer and use it in GitHub Desktop.
Example of declaring and loading namespace packages
This file contains 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
# dirs/c/xx_plugins/c_module/__init__.py | |
# dirs/c/xx_plugins/d_module/__init__.py | |
# dirs/a/b/xx_plugins/ab_module/__init__.py | |
import sys | |
import os.path as op | |
import importlib | |
import pkgutil | |
from types import ModuleType | |
from typing import List | |
def _import_namespace(namespace: str): | |
ns = importlib.import_module(namespace) | |
if not hasattr(ns, '__path__') and getattr(ns, '__file__', None): | |
raise TypeError(f'module {namespace} is not a namespace module') | |
modules = [] | |
for spec in pkgutil.iter_modules(ns.__path__): | |
fqn = '.'.join([namespace, spec.name]) | |
loader = pkgutil.get_loader(fqn) | |
module = loader.load_module(fqn) | |
modules.append(module) | |
return ns, modules | |
def import_namespace_modules(namespace: str, module_dirs: List[str]): | |
module_dirs = list(map(op.abspath, module_dirs)) | |
for path in module_dirs: | |
sys.path.insert(0, path) | |
try: | |
return _import_namespace(namespace) | |
except: | |
raise | |
finally: | |
for path in module_dirs: | |
if path in sys.path: | |
sys.path.remove(path) | |
return None, None | |
module_paths = ['dirs/a/b', 'dirs/c'] | |
ns, modules = import_namespace_modules('xx_plugins', module_paths) | |
from xx_plugins import d_module | |
print(d_module) |
This file contains 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
dirs/c/xx_plugins/c_module/__init__.py0000664000175000017500000000007614060254606020301 0ustar mcuttermcutter | |
print('C imported') | |
def c_func(): | |
print('C func called')dirs/c/xx_plugins/d_module/__init__.py0000664000175000017500000000011514060254565020300 0ustar mcuttermcutter | |
print('D module loaded') | |
from xx_plugins.c_module import c_func | |
c_func() | |
dirs/a/b/xx_plugins/ab_module/__init__.py0000664000175000017500000000002614060251722020647 0ustar mcuttermcutter | |
print('AB imported') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment