Source code for schrodinger.models.advanced_mappers
from schrodinger.models import mappers
[docs]class ModelBaseClassMapperMixin(mappers.MapperMixin):
    """
    A mapper mixin that allows any model class that is a subclass of a
    specified base class. Unlike a standard MapperMixin, the mapper is re-
    generated every time a new model is set, and the model_class class variable
    is updated to the class of the new model.
    This allows mappings to vary depending on the characteristics of the model
    class (for example, values of class attributes, presence or absence of
    specific params, etc.).
    To use, set the model_base_class class variable to the base class of all
    models that will be used with this mapper.
    """
    model_base_class = None
    def _setupMapperMixin(self):
        if self.model_class is not None:
            raise ValueError('The model_class class variable should not be '
                             'defined for a ModelBaseClassMapperMixin %s. '
                             'Define the model_classes tuple instead.' %
                             self.__class__.__name__)
        self.model_class = self.model_base_class
        super()._setupMapperMixin()
    def _setupModelClass(self, model):
        super()._setupModelClass(model)
        if not isinstance(model, self.model_base_class):
            raise TypeError(f'Model must be a subclass of '
                            f'{self.model_base_class}. Got {type(model)}')
        self.model_class = type(model)
        self._buildMapper() 
[docs]class MultiModelClassMapperMixin(mappers.MapperMixin):
    """
    A mapper mixin that allows multiple model classes. To use, define the
    model_classes tuple with all the allowable model classes. Then define the
    usual defineMappings and getSignalsAndSlots methods, which are allowed to
    branch on self.model_class to specify model class-specific mappings and
    signal/slot connections.
    In use, self.model_class will be set to one of the classes in
    self.model_classes, depending on what the current model is.
    """
    model_classes = tuple()
    def _setupMapperMixin(self):
        if self.model_class is not None:
            raise ValueError('The model_class class variable should not be '
                             'defined for a MultiModelClassMapperMixin %s. '
                             'Define the model_classes tuple instead.' %
                             self.__class__.__name__)
        if not self.model_classes:
            raise ValueError('The model_classes variable must be non-empty.')
        self.model_class = self.model_classes[0]
        super()._setupMapperMixin()
    def _setupModelClass(self, model):
        super()._setupModelClass(model)
        for model_class in self.model_classes:
            if isinstance(model, model_class):
                self.model_class = model_class
                break
        else:
            raise TypeError(f'Model must be one of {self.model_classes}. '
                            f'Got {type(model)}')
        self._buildMapper()