Skip to content

Commit

Permalink
Completed the import package define
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom authored and Tom committed Jul 25, 2017
1 parent 1597ade commit 040611f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 42 deletions.
1 change: 1 addition & 0 deletions malcolm/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
UnexpectedError
from .future import Future
from .hook import Hook
from .importer import Importer
from .info import Info
from .loggable import Loggable
from .map import Map
Expand Down
57 changes: 57 additions & 0 deletions malcolm/core/importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os
import sys
import importlib
import logging
import types
import imp

# Create a module level logger
log = logging.getLogger(__name__)


class Importer(object):
def __init__(self, ):
self.special_names = [
"vmetas", "infos", "controllers", "parts", "includes", "blocks"]

def import_all_packages(self, root_package, root_init, globals_d):
"""Import any packages relative to self.root_dir, recursing down one
level to specially named subdirs"""
modules = {}
root_dir = os.path.dirname(root_init)
for f in os.listdir(root_dir):
if os.path.isfile(os.path.join(root_dir, f, "__init__.py")):
name = ".".join([root_package, f])
modules.update(self.try_import_name(name))
pkg_dir = os.path.join(root_dir, f)
self.import_special_subpackages(name, pkg_dir)
globals_d.update(modules)
return list(modules)

def import_special_subpackages(self, name, path):
"""Import specially named subpackages of name"""
for n in self.special_names:
sub_dir = os.path.join(path, n)
if os.path.isdir(sub_dir) or os.path.isfile(sub_dir + ".py"):
self.try_import_name(".".join([name, n]))

def try_import_name(self, name):
try:
imp = importlib.import_module(name)
except ImportError:
log.warning("Importing %s failed", name, exc_info=True)
return {}
else:
return {name: imp}

def import_package_from_path(self, name, path):
dirname, basename = path.rsplit(os.sep, 1)
file, pathname, description = imp.find_module(basename, [dirname])
try:
mod = imp.load_module(name, file, pathname, description)
finally:
if file is not None:
file.close()
parent_name, attr_name = name.rsplit(".", 1)
parent = importlib.import_module(parent_name)
setattr(parent, attr_name, mod)
36 changes: 2 additions & 34 deletions malcolm/modules/__init__.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,5 @@
class Importer(object):
def __init__(self):
self.update_dict = {}
self.dirnames = [
"vmetas", "infos", "controllers", "parts", "includes", "blocks"]
from malcolm.core import Importer

def import_subpackages(self, path, filter=()):
import os
dirname = os.path.join(os.path.dirname(__file__), *path)
for f in os.listdir(dirname):
if not filter or f in filter:
if os.path.isdir(os.path.join(dirname, f)):
self.try_import_path(path + [f])
# Try the import of subpackages too
self.import_subpackages(path + [f], self.dirnames)

def try_import_path(self, path):
import importlib
name = ".".join(path)
try:
self.update_dict[name] = importlib.import_module(
"malcolm.modules.%s" % name)
except ImportError:
import logging
# Create a module level logger
log = logging.getLogger(__name__)
log.warning("Importing %s failed", name, exc_info=True)

def prepare(self, globals_d):
self.import_subpackages([])
globals_d.update(self.update_dict)
__all__ = list(self.update_dict)
return __all__

__all__ = Importer().prepare(globals())
__all__ = Importer().import_all_packages(__name__, __file__, globals())

del Importer
13 changes: 5 additions & 8 deletions malcolm/modules/builtin/defines.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import types
import sys

from malcolm.core import method_takes, REQUIRED
from malcolm.core import method_takes, REQUIRED, Importer
from malcolm.modules.builtin.vmetas import StringMeta, NumberMeta


Expand Down Expand Up @@ -78,12 +78,9 @@ def export_env_string(params):
"malcolm.modules.<name>"), REQUIRED)
def module_path(params):
"""Load an external malcolm module (e.g. ADCore/etc/malcolm)"""
import malcolm.modules
path = os.path.join(params.path, "__init__.py")
assert os.path.isfile(path), "%r doesn't exist" % path
importer = Importer()
assert os.path.isdir(params.path), "%r doesn't exist" % params.path
name = "malcolm.modules.%s" % params.name
created_module = types.ModuleType(name)
sys.modules[name] = created_module
execfile(path, created_module.__dict__)
setattr(malcolm.modules, params.name, created_module)
importer.import_package_from_path(name, params.path)
importer.import_special_subpackages(name, params.path)
return {params.name: params.path}

0 comments on commit 040611f

Please sign in to comment.