def init_prop(self, obj, value=_Default): if value is _Default: value = self.get_default(obj) new_value = (_none if value is _none else self.type_safe_value( value, _none_ok=True)) if new_value is _none: if self.required: raise exc.PropertyRequired(prop=self) else: obj.__dict__[self.name] = new_value
def type_safe_value(self, value, _none_ok=False): if value is None and self.required and not self.valuetype: raise exc.PropertyRequired(prop=self) if self.valuetype and not isinstance(value, self.valuetype): try: new_value = self.coerce(value) except exc.SubtypeCoerceError as e: # this particular coerce error will be re-caught below, # unless the coerce method returned None new_value = e.coerced except Exception as e: raise exc.CoerceError( prop=self, passed=value, exc=e, func=( "%s constructor" % self.coerce.__name__ if isinstance(self.coerce, type) else self.coerce ), valuetype=( "(" + ", ".join( x.__name__ for x in self.valuetype ) + ")" if isinstance(self.valuetype, tuple) else self.valuetype.__name__ ), ) if not isinstance(new_value, self.valuetype): if _none_ok and new_value is None and not self.required: # allow coerce functions to return 'None' to silently # swallow optional properties on initialization return _none else: raise exc.ValueCoercionError( prop=self, passed=value, coerced=new_value, ) else: value = new_value if self.check and not self.check(value): raise exc.ValueCheckError( prop=self, passed=value, ) return value
def __delete__(self, obj): """Checks the property's ``required`` setting, and allows the delete if it is false""" if self.required: raise exc.PropertyRequired(prop=self) del obj.__dict__[self.name]