diff options
Diffstat (limited to 'warlock/core.py')
-rw-r--r-- | warlock/core.py | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/warlock/core.py b/warlock/core.py index eacd7ab..ad3f3bd 100644 --- a/warlock/core.py +++ b/warlock/core.py @@ -27,16 +27,20 @@ def model_factory(schema): except jsonschema.ValidationError: raise ValidationError() - class Model(object): + class Model(dict): """Self-validating model for arbitrary objects""" - def __init__(self, **kwargs): + + def __init__(self, *args, **kwargs): + d = dict(*args, **kwargs) + + # we overload setattr so set this manually self.__dict__['validator'] = validator try: - self.__dict__['validator'](kwargs) + self.validator(d) except ValidationError: raise ValueError() else: - self.__dict__['raw'] = kwargs + dict.__init__(self, d) self.__dict__['changes'] = {} @@ -46,27 +50,57 @@ def model_factory(schema): except KeyError: raise AttributeError(key) - def __getitem__(self, key): - return self.__dict__['raw'][key] - def __setitem__(self, key, value): - mutation = copy.deepcopy(self.__dict__['raw']) + mutation = dict(self.items()) mutation[key] = value try: - self.__dict__['validator'](mutation) + self.validator(mutation) except ValidationError: raise InvalidOperation() - self.__dict__['raw'] = mutation + + dict.__setitem__(self, key, value) + self.__dict__['changes'][key] = value def __setattr__(self, key, value): self.__setitem__(key, value) + def clear(self): + raise InvalidOperation() + + def pop(self, key, default=None): + raise InvalidOperation() + + def popitem(self): + raise InvalidOperation() + + def __delitem__(self, key): + raise InvalidOperation() + + # NOTE(termie): This is kind of the opposite of what copy usually does + def copy(self): + return copy.deepcopy(dict(self)) + + def update(self, other): + mutation = dict(self.items()) + mutation.update(other) + try: + self.validator(mutation) + except ValidationError: + raise InvalidOperation() + dict.update(self, other) + def iteritems(self): - return copy.deepcopy(self.__dict__['raw']).iteritems() + return copy.deepcopy(dict(self)).iteritems() def items(self): - return copy.deepcopy(self.__dict__['raw']).items() + return copy.deepcopy(dict(self)).items() + + def itervalues(self): + return copy.deepcopy(dict(self)).itervalues() + + def values(self): + return copy.deepcopy(dict(self)).values() @property def changes(self): |