def test_multiple(self): superclasses_of_a_or_b = SuperclassesOf(self.A, self.B) self.assertEqual((self.A, self.B), superclasses_of_a_or_b.types) self.assertTrue(superclasses_of_a_or_b.satisfied_by(self.A())) self.assertTrue(superclasses_of_a_or_b.satisfied_by(self.B())) self.assertFalse(superclasses_of_a_or_b.satisfied_by(self.BPrime())) self.assertFalse(superclasses_of_a_or_b.satisfied_by(self.C()))
def test_single(self): superclasses_of_b = SuperclassesOf(self.B) self.assertEqual((self.B,), superclasses_of_b.types) self.assertTrue(superclasses_of_b.satisfied_by(self.A())) self.assertTrue(superclasses_of_b.satisfied_by(self.B())) self.assertFalse(superclasses_of_b.satisfied_by(self.BPrime())) self.assertFalse(superclasses_of_b.satisfied_by(self.C()))
def test_single(self): superclasses_of_b = SuperclassesOf(self.B) self.assertEqual((self.B, ), superclasses_of_b.types) self.assertTrue(superclasses_of_b.satisfied_by(self.A())) self.assertTrue(superclasses_of_b.satisfied_by(self.B())) self.assertFalse(superclasses_of_b.satisfied_by(self.BPrime())) self.assertFalse(superclasses_of_b.satisfied_by(self.C()))
def __init__(self, abstract=False, extends=None, merges=None, **kwargs): """Creates a new configuration data blob. By default configurations are anonymous (un-named), concrete (not `abstract`), and they neither inherit nor merge another configuration. Inheritance is only allowed via one of the `extends` or `merges` channels, it is an error to specify both. A configuration can be semantically abstract without setting `abstract=True`. The `abstract` value can serve as documentation, or, for subclasses that provide an implementation for `validate_concrete`, it allows skipping validation for abstract instances. :param bool abstract: `True` to mark this configuration item as abstract, in which case no validation is performed (see `validate_concrete`); `False` by default. :param extends: The configuration instance to inherit field values from. Any shared fields are over-written with this instances values. :type extends: An addressed or concrete configuration instance that is a type compatible with this configuration or this configurations superclasses. :param merges: The configuration instance to merge this instances field values with. Merging is like extension except for containers, which are extended instead of replaced; ie: any `dict` values are updated with this instances items and any `list` values are extended with this instances items. :type merges: An addressed or concrete configuration instance that is a type compatible with this configuration or this configurations superclasses. :param **kwargs: The configuration parameters. """ self._kwargs = kwargs self._kwargs['abstract'] = abstract # It only makes sense to inherit a subset of our own fields (we should not inherit new fields!), # our superclasses logically provide fields within this constrained set. # NB: Since Configuration is at base an ~unconstrained struct, a superclass does allow for # arbitrary and thus more fields to be defined than a subclass might logically support. We # accept this hole in a trade for generally expected behavior when Configuration is subclassed # in the style of constructors with named parameters representing the full complete set of # expected parameters leaving **kwargs only for use by 'the system'; ie for `typename` and # `address` plumbing for example. self._kwargs['extends'] = addressable(SuperclassesOf(type(self)), extends) self._kwargs['merges'] = addressable(SuperclassesOf(type(self)), merges) # Allow for configuration items that are directly constructed in memory. These can have an # address directly assigned (vs. inferred from name + source file location) and we only require # that if they do, their name - if also assigned, matches the address. if self.address: if self.name and self.name != self.address.target_name: self.report_validation_error( 'Address and name do not match! address: {}, name: {}'. format(self.address, self.name)) self._kwargs['name'] = self.address.target_name self._hashable_key = None
def test(self): self.assertTrue(SuperclassesOf(self.B).satisfied_by(self.A())) self.assertTrue(SuperclassesOf(self.B).satisfied_by(self.B())) self.assertFalse(SuperclassesOf(self.B).satisfied_by(self.BPrime())) self.assertFalse(SuperclassesOf(self.B).satisfied_by(self.C()))