def test_convert_load(self): """ Test that the convert method returns the loaded entry point if load=True at construction time of parameter """ param = PluginParamType(group=('transports', 'data'), load=True) entry_point_ssh = get_entry_point_from_string('aiida.transports:ssh') entry_point_structure = get_entry_point_from_string( 'aiida.data:structure') entry_point = param.convert('aiida.transports:ssh', None, None) self.assertTrue(entry_point, entry_point_ssh) entry_point = param.convert('transports:ssh', None, None) self.assertTrue(entry_point, entry_point_ssh) entry_point = param.convert('ssh', None, None) self.assertTrue(entry_point, entry_point_ssh) entry_point = param.convert('aiida.data:structure', None, None) self.assertTrue(entry_point, entry_point_structure) entry_point = param.convert('data:structure', None, None) self.assertTrue(entry_point, entry_point_structure) entry_point = param.convert('structure', None, None) self.assertTrue(entry_point, entry_point_structure) with self.assertRaises(click.BadParameter): param.convert('not_existent', None, None)
def __init__(self, sub_classes=None): """ Construct the parameter type, optionally specifying a tuple of entry points that reference classes that should be a sub class of the base orm class of the orm class loader. The classes pointed to by these entry points will be passed to the OrmEntityLoader when converting an identifier and they will restrict the query set by demanding that the class of the corresponding entity matches these sub classes. To prevent having to load the database environment at import time, the actual loading of the entry points is deferred until the call to `convert` is made. This is to keep the command line autocompletion light and responsive. The entry point strings will be validated, however, to see if the correspond to known entry points. :param sub_classes: a tuple of entry point strings that can narrow the set of orm classes that values will be mapped upon. These classes have to be strict sub classes of the base orm class defined by the orm class loader """ from aiida.common import exceptions self._sub_classes = None self._entry_points = [] if sub_classes is not None: if not isinstance(sub_classes, tuple): raise TypeError('sub_classes should be a tuple of entry point strings') for entry_point_string in sub_classes: try: entry_point = get_entry_point_from_string(entry_point_string) except (ValueError, exceptions.EntryPointError) as exception: raise ValueError('{} is not a valid entry point string: {}'.format(entry_point_string, exception)) else: self._entry_points.append(entry_point)
def tools(self): """Return the calculation tools that are registered for the process type associated with this calculation. If the entry point name stored in the `process_type` of the CalcJobNode has an accompanying entry point in the `aiida.tools.calculations` entry point category, it will attempt to load the entry point and instantiate it passing the node to the constructor. If the entry point does not exist, cannot be resolved or loaded, a warning will be logged and the base CalculationTools class will be instantiated and returned. :return: CalculationTools instance """ from aiida.plugins.entry_point import is_valid_entry_point_string, get_entry_point_from_string, load_entry_point from aiida.tools.calculations import CalculationTools if self._tools is None: entry_point_string = self.process_type if is_valid_entry_point_string(entry_point_string): entry_point = get_entry_point_from_string(entry_point_string) try: tools_class = load_entry_point('aiida.tools.calculations', entry_point.name) self._tools = tools_class(self) except exceptions.EntryPointError as exception: self._tools = CalculationTools(self) self.logger.warning( f'could not load the calculation tools entry point {entry_point.name}: {exception}' ) return self._tools
def test_get_entry_point_from_string(self): """ Test the functionality of the get_entry_point_from_string which will take an entry point string and try to map it onto a valid entry point that is part of the groups defined for the parameter. """ param = PluginParamType(group='calculations') entry_point = get_entry_point_from_string('aiida.calculations:job') # Invalid entry point strings with self.assertRaises(ValueError): param.get_entry_point_from_string('aiida.calculation:job') with self.assertRaises(ValueError): param.get_entry_point_from_string('aiid.calculations:job') with self.assertRaises(ValueError): param.get_entry_point_from_string('aiida..calculations:job') # Unsupported entry points for all formats with self.assertRaises(ValueError): param.get_entry_point_from_string('aiida.data:structure') with self.assertRaises(ValueError): param.get_entry_point_from_string('data:structure') with self.assertRaises(ValueError): param.get_entry_point_from_string('structure') # Non-existent entry points for all formats with self.assertRaises(ValueError): param.get_entry_point_from_string( 'aiida.calculations:not_existent') with self.assertRaises(ValueError): param.get_entry_point_from_string('calculations:not_existent') with self.assertRaises(ValueError): param.get_entry_point_from_string('not_existent') # Valid entry point strings self.assertEquals( param.get_entry_point_from_string('aiida.calculations:job').name, entry_point.name) self.assertEquals( param.get_entry_point_from_string('calculations:job').name, entry_point.name) self.assertEquals( param.get_entry_point_from_string('job').name, entry_point.name)
def test_get_entry_point_from_ambiguous(self): """ Test the functionality of the get_entry_point_from_string which will take an entry point string and try to map it onto a valid entry point that is part of the groups defined for the parameter. """ param = PluginParamType(group=('aiida.calculations', 'aiida.parsers')) entry_point = get_entry_point_from_string( 'aiida.calculations:arithmetic.add') # Both groups contain entry point `arithmetic.add` so passing only name is ambiguous and should raise with self.assertRaises(ValueError): param.get_entry_point_from_string('arithmetic.add') # Passing PARTIAL or FULL should allow entry point to be returned self.assertEqual( param.get_entry_point_from_string( 'aiida.calculations:arithmetic.add').name, entry_point.name) self.assertEqual( param.get_entry_point_from_string( 'calculations:arithmetic.add').name, entry_point.name)