Source code for slash.core.metadata

import itertools
import sys

from ..ctx import context
from ..exceptions import SlashInternalError

_sort_key_generator = itertools.count(1)

[docs]class Metadata(object): """Class representing the metadata associated with a test object. Generally available as test.__slash__ """ #: The index of the test in the current execution, 0-based test_index0 = None def __init__(self, factory, test): super(Metadata, self).__init__() #: The test's unique id self.id = None self.tags = test.get_tags() self._sort_key = next(_sort_key_generator) self.repeat_all_index = 0 self.parallel_index = None if factory is not None: #: The path to the file from which this test was loaded self.module_name = factory.get_module_name() if not self.module_name: raise SlashInternalError('Could not find module for {}'.format(test)) self._file_path = factory.get_filename() self.factory_name = factory.get_factory_name() else: self.module_name = type(test).__module__ self._file_path = sys.modules[self.module_name].__file__ self.factory_name = '?' self.variation = test.get_variation() if self.variation is None: raise SlashInternalError('{} has no variations'.format(test)) self._address_override = None #: Address string to identify the test inside the file from which it was loaded self.address_in_file = self.factory_name self.address_in_factory = test.get_address_in_factory() if self.address_in_factory is not None: self.address_in_file += self.address_in_factory if factory is not None: self._class_name = factory.get_class_name() else: testfunc = test.get_test_function() if hasattr(testfunc, '__self__'): self._class_name = testfunc.__self__.__class__.__name__ else: self._class_name = None self._interactive = False def set_file_path(self, file_path): self._file_path = file_path @property def file_path(self): return self._file_path
[docs] def get_address(self, raw_params=False): """ String identifying the test, to be used when logging or displaying results in the console generally it is composed of the file path and the address inside the file :param raw_params: If ``True``, emit the full parametrization values are interpolated into the returned string """ if self._address_override is not None: return self._address_override returned = '{}:{}'.format(self.file_path, self.address_in_file) if self.variation: returned += '({})'.format( ', '.join('{}={!r}'.format(key, value) for key, value in self.variation.values.items()) if raw_params else self.variation.safe_repr ) return returned
address = property(get_address) def allocate_id(self): if self.id is not None: raise SlashInternalError('id field of metadata object should be None, is {}'.format(self.id)) self.id = context.session.id_space.allocate() def set_sort_key(self, key): self._sort_key = key def get_sort_key(self): return self._sort_key def set_test_full_name(self, name): assert hasattr(self, '_address_override') self._address_override = name def is_interactive(self): return self._interactive def mark_interactive(self): self._interactive = True self.set_sort_key(0) @property def class_name(self): return self._class_name @property def function_name(self): returned = self.address_in_file if self._class_name: prefix = self._class_name + '.' assert returned.startswith(prefix) returned = returned[len(prefix):] return returned.split('(')[0] @property def test_index1(self): """Same as ``test_index0``, only 1-based """ if self.test_index0 is None: return None return self.test_index0 + 1 def __repr__(self): return '<{}>'.format(self.address) def __eq__(self, other): if isinstance(other, self.__class__): return self.address == other.address return False def __ne__(self, other): return not (self == other) # pylint: disable=superfluous-parens,unneeded-not def __hash__(self): return self.address.__hash__()
def ensure_test_metadata(test): returned = getattr(test, "__slash__", None) if returned is None: returned = test.__slash__ = Metadata(None, test) return returned