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()