From 01b2b8c689cf2dfcfee5e21fe1b8277b09f5e8d8 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Wed, 14 Mar 2012 16:50:46 -0400 Subject: [PATCH] A utility function to import a class from a module given syntax such as used by nose and setuptools entry points. --- devstack/importer.py | 19 +++++++++++++++++++ tests/test_importer.py | 13 +++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 devstack/importer.py create mode 100644 tests/test_importer.py diff --git a/devstack/importer.py b/devstack/importer.py new file mode 100644 index 00000000..31204f42 --- /dev/null +++ b/devstack/importer.py @@ -0,0 +1,19 @@ + + +def import_entry_point(fullname): + """Given a name import the class and return it. + + The name should be in dotted.path:ClassName syntax. + """ + if ':' not in fullname: + raise ValueError('Invalid entry point specifier %r' % fullname) + module_name, ignore, classname = fullname.partition(':') + try: + module = __import__(module_name) + for submodule in module_name.split('.')[1:]: + module = getattr(module, submodule) + cls = getattr(module, classname) + except (ImportError, AttributeError) as err: + raise RuntimeError('Could not load entry point %s: %s' % + (fullname, err)) + return cls diff --git a/tests/test_importer.py b/tests/test_importer.py new file mode 100644 index 00000000..07e80ea7 --- /dev/null +++ b/tests/test_importer.py @@ -0,0 +1,13 @@ + +from devstack import importer +from devstack import distro + + +def test_function(): + f = importer.import_entry_point('devstack.importer:import_entry_point') + assert f == importer.import_entry_point + + +def test_class(): + c = importer.import_entry_point('devstack.distro:Distro') + assert c == distro.Distro