diff --git a/qubes/__init__.py b/qubes/__init__.py index 3c4c292e..433e8e2c 100644 --- a/qubes/__init__.py +++ b/qubes/__init__.py @@ -81,6 +81,18 @@ except ImportError: pass +def get_entry_point_one(group, name): + epoints = tuple(pkg_resources.iter_entry_points(group, name)) + if not epoints: + raise KeyError(name) + elif len(epoints) > 1: + raise TypeError( + 'more than 1 implementation of {!r} found: {}'.format(name, + ', '.join('{}.{}'.format(ep.module_name, '.'.join(ep.attrs)) + for ep in epoints))) + return epoints[0].load() + + class VMMConnection(object): '''Connection to Virtual Machine Manager (libvirt)''' @@ -1401,18 +1413,13 @@ class Qubes(PropertyHolder): :param str clsname: name of the class :return type: class ''' - epoints = tuple(pkg_resources.iter_entry_points('qubes.vm', clsname)) - if not epoints: + + try: + get_entry_point_one('qubes.vm', clsname) + except KeyError: raise qubes.exc.QubesException( 'no such VM class: {!r}'.format(clsname)) - elif len(epoints) > 1: - raise qubes.exc.QubesException( - 'more than 1 implementation of {!r} found: {}'.format( - clsname, - ', '.join( - '{}.{}'.format(ep.module_name, '.'.join(ep.attrs)) - for ep in epoints))) - return epoints[0].load() + # don't catch TypeError def add_new_vm(self, cls, qid=None, **kwargs): diff --git a/qubes/devices.py b/qubes/devices.py index f384dc19..11a4be68 100644 --- a/qubes/devices.py +++ b/qubes/devices.py @@ -24,6 +24,8 @@ import re +import qubes + class DeviceCollection(object): '''Bag for devices. @@ -45,6 +47,14 @@ class DeviceCollection(object): :param str device: device identifier (format is class-dependent) ''' + try: + devclass = qubes.get_entry_point_one('qubes.devices', self._class) + except KeyError: + devclass = str + + if not isinstance(device, devclass): + device = devclass(device) + if device in self: raise KeyError( 'device {!r} of class {} already attached to {!r}'.format( diff --git a/setup.py b/setup.py index aaaa709b..f8789ccf 100644 --- a/setup.py +++ b/setup.py @@ -39,5 +39,8 @@ if __name__ == '__main__': 'qubes.ext.gui = qubes.ext.gui:GUI', 'qubes.ext.r3compatibility = qubes.ext.r3compatibility:R3Compatibility', ], + 'qubes.devices': [ + 'pci = qubes.devices:PCIDevice', + ], } )