From 43b5a14c19e8a5544c6913cada4caa1a967cf7dc Mon Sep 17 00:00:00 2001 From: Tom Cobb Date: Fri, 29 Jul 2016 11:02:21 +0100 Subject: [PATCH] Auto export controllers --- malcolm/controllers/__init__.py | 13 +++++--- malcolm/controllers/clientcontroller.py | 3 +- malcolm/controllers/countercontroller.py | 1 + malcolm/controllers/hellocontroller.py | 1 + .../controllers/scanpointtickercontroller.py | 1 + malcolm/core/package.py | 28 ----------------- malcolm/util.py | 31 +++++++++++++++++++ 7 files changed, 44 insertions(+), 34 deletions(-) delete mode 100644 malcolm/core/package.py create mode 100644 malcolm/util.py diff --git a/malcolm/controllers/__init__.py b/malcolm/controllers/__init__.py index b394c145e..5b6de7999 100644 --- a/malcolm/controllers/__init__.py +++ b/malcolm/controllers/__init__.py @@ -1,7 +1,10 @@ # make the import path nice -from malcolm.controllers.clientcontroller import ClientController # noqa -from malcolm.controllers.countercontroller import CounterController # noqa -from malcolm.controllers.hellocontroller import HelloController # noqa -from malcolm.controllers.scanpointtickercontroller import \ - ScanPointTickerController # noqa +from malcolm.util import import_child_packages +class_dict = import_child_packages("controllers") + +globals().update(class_dict) +__all__ = list(class_dict) + +del class_dict +del import_child_packages diff --git a/malcolm/controllers/clientcontroller.py b/malcolm/controllers/clientcontroller.py index 25f6da2ac..2a91cc85f 100644 --- a/malcolm/controllers/clientcontroller.py +++ b/malcolm/controllers/clientcontroller.py @@ -3,10 +3,11 @@ from malcolm.core.controller import Controller from malcolm.core.request import Post, Subscribe from malcolm.core.response import Return -from malcolm.core.method import Method +from malcolm.core.method import Method, takes from malcolm.core.serializable import Serializable +@takes() class ClientController(Controller): """Sync a local block with a given remote block""" REMOTE_BLOCKS_ID = 0 diff --git a/malcolm/controllers/countercontroller.py b/malcolm/controllers/countercontroller.py index cb2aa9c20..30f73c414 100644 --- a/malcolm/controllers/countercontroller.py +++ b/malcolm/controllers/countercontroller.py @@ -6,6 +6,7 @@ from malcolm.metas import NumberMeta +@takes() class CounterController(Controller): def create_attributes(self): diff --git a/malcolm/controllers/hellocontroller.py b/malcolm/controllers/hellocontroller.py index 695a4efcd..2a6827ee4 100644 --- a/malcolm/controllers/hellocontroller.py +++ b/malcolm/controllers/hellocontroller.py @@ -3,6 +3,7 @@ from malcolm.core.method import takes, returns, REQUIRED +@takes() class HelloController(Controller): @takes(StringMeta("name", "a name"), REQUIRED) @returns(StringMeta("greeting", "a greeting"), REQUIRED) diff --git a/malcolm/controllers/scanpointtickercontroller.py b/malcolm/controllers/scanpointtickercontroller.py index e239d19b6..efcfd0230 100644 --- a/malcolm/controllers/scanpointtickercontroller.py +++ b/malcolm/controllers/scanpointtickercontroller.py @@ -9,6 +9,7 @@ @RunnableDeviceStateMachine.insert +@takes() class ScanPointTickerController(Controller): def create_attributes(self): diff --git a/malcolm/core/package.py b/malcolm/core/package.py deleted file mode 100644 index 36b99821f..000000000 --- a/malcolm/core/package.py +++ /dev/null @@ -1,28 +0,0 @@ -import os -import importlib - -from malcolm.core.serializable import Serializable - - -def register_package(package_name): - """Prepare a package namespace by importing all subclasses following PEP8 - rules, and registering any @takes decorated functions""" - class_dict = {} - malcolm_path = os.path.join(os.path.dirname(__file__), "..") - # this is the path to the package - package_path = os.path.join(malcolm_path, package_name) - for f in os.listdir(package_path): - if f.endswith(".py") and f != "__init__.py": - # import it and see what it produces - module_name = f[:-3] - module = importlib.import_module( - "malcolm.%s.%s" % (package_name, module_name)) - for n in dir(module): - if n.lower() == module_name: - cls = getattr(module, n) - if hasattr(cls, "Method"): - # we have something! - class_dict[cls.__name__] = cls - register_name = "%s.%s" % (package_name, cls.__name__) - Serializable.register_subclass(register_name)(cls) - return class_dict diff --git a/malcolm/util.py b/malcolm/util.py new file mode 100644 index 000000000..cc1772b84 --- /dev/null +++ b/malcolm/util.py @@ -0,0 +1,31 @@ +import os +import importlib +import logging + + +def import_child_packages(package_name): + """Prepare a package namespace by importing all subclasses following PEP8 + rules that have @takes decorated functions""" + class_dict = {} + # this is the path to the package + package_path = os.path.join(os.path.dirname(__file__), package_name) + for f in os.listdir(package_path): + if f.endswith(".py") and f != "__init__.py": + # import it and see what it produces + module_name = f[:-3] + module = importlib.import_module( + "malcolm.%s.%s" % (package_name, module_name)) + for cls in find_decorated_classes(module): + class_dict[cls.__name__] = cls + return class_dict + +def find_decorated_classes(module): + for n in dir(module): + cls = getattr(module, n) + if hasattr(cls, "Method"): + module_name = module.__name__.split(".")[-1] + if n.lower() != module_name: + logging.warning("Classname %s when lower cased should be %s" % + (n, module_name)) + logging.debug("Found child class %s" % cls) + yield cls