summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob <rob.s.brit@gmail.com>2012-11-27 11:16:13 -0500
committerBrian Waldon <bcwaldon@gmail.com>2012-12-22 15:39:09 -0800
commit98a44c660136b7089cf3e8ed95254b475ab4d085 (patch)
treed5ddbceef40053632558b96e72fffcbeaa123f07
parente8f0a5ade79156cfe18ae5ec25c5737cc1f7e532 (diff)
downloadwarlock-98a44c660136b7089cf3e8ed95254b475ab4d085.tar.gz
Break up core pieces into separate modules
- Create model.py to hold the core Model class - Create exceptions.py to hold all custom exceptions
-rw-r--r--.gitignore2
-rw-r--r--warlock/__init__.py2
-rw-r--r--warlock/core.py112
-rw-r--r--warlock/exceptions.py9
-rw-r--r--warlock/model.py108
5 files changed, 127 insertions, 106 deletions
diff --git a/.gitignore b/.gitignore
index 59ae20d..cce7553 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@ build/
dist/
warlock.egg-info/
.tox/
+*.swp
+*.pyc
diff --git a/warlock/__init__.py b/warlock/__init__.py
index 400c081..0d8560e 100644
--- a/warlock/__init__.py
+++ b/warlock/__init__.py
@@ -2,4 +2,4 @@
# pylint: disable=W0611
from warlock.core import model_factory
-from warlock.core import InvalidOperation
+from warlock.exceptions import InvalidOperation
diff --git a/warlock/core.py b/warlock/core.py
index 9c3cdf7..5717399 100644
--- a/warlock/core.py
+++ b/warlock/core.py
@@ -3,18 +3,12 @@
import copy
import jsonschema
-import jsonpatch
+import model
+import exceptions
-class InvalidOperation(RuntimeError):
- pass
-
-class ValidationError(ValueError):
- pass
-
-
-def model_factory(schema):
+def model_factory(schema, base_class=model.Model):
"""Generate a model class based on the provided JSON Schema
:param schema: dict representing valid JSON schema
@@ -26,104 +20,12 @@ def model_factory(schema):
try:
jsonschema.validate(obj, schema)
except jsonschema.ValidationError as exc:
- raise ValidationError(str(exc))
-
- class Model(dict):
- """Self-validating model for arbitrary objects"""
+ raise exceptions.ValidationError(str(exc))
+ class Model(base_class):
def __init__(self, *args, **kwargs):
- d = dict(*args, **kwargs)
-
- # we overload setattr so set this manually
- self.__dict__['validator'] = validator
- try:
- self.validator(d)
- except ValidationError as exc:
- raise ValueError(str(exc))
- else:
- dict.__init__(self, d)
-
- self.__dict__['changes'] = {}
- self.__dict__['__original__'] = copy.deepcopy(d)
-
- def __getattr__(self, key):
- try:
- return self.__getitem__(key)
- except KeyError:
- raise AttributeError(key)
-
- def __setitem__(self, key, value):
- mutation = dict(self.items())
- mutation[key] = value
- try:
- self.validator(mutation)
- except ValidationError:
- msg = "Unable to set '%s' to '%s'" % (key, value)
- raise InvalidOperation(msg)
-
- 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):
- mutation = dict(self.items())
- del mutation[key]
- try:
- self.validator(mutation)
- except ValidationError:
- msg = "Unable to delete attribute '%s'" % (key)
- raise InvalidOperation(msg)
-
- dict.__delitem__(self, key)
-
- def __delattr__(self, key):
- self.__delitem__(key)
-
- # 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 as exc:
- raise InvalidOperation(str(exc))
- dict.update(self, other)
-
- def iteritems(self):
- return copy.deepcopy(dict(self)).iteritems()
-
- def items(self):
- 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):
- return copy.deepcopy(self.__dict__['changes'])
-
- @property
- def patch(self):
- original = self.__dict__['__original__']
- return jsonpatch.make_patch(original, dict(self)).to_string()
+ kwargs.setdefault('validator', validator)
+ base_class.__init__(self, *args, **kwargs)
Model.__name__ = str(schema['name'])
return Model
diff --git a/warlock/exceptions.py b/warlock/exceptions.py
new file mode 100644
index 0000000..01d72da
--- /dev/null
+++ b/warlock/exceptions.py
@@ -0,0 +1,9 @@
+""" List of errors used in warlock """
+
+
+class InvalidOperation(RuntimeError):
+ pass
+
+
+class ValidationError(ValueError):
+ pass
diff --git a/warlock/model.py b/warlock/model.py
new file mode 100644
index 0000000..6dff70a
--- /dev/null
+++ b/warlock/model.py
@@ -0,0 +1,108 @@
+"""Self-validating model for arbitrary objects"""
+
+import copy
+
+import jsonpatch
+
+import exceptions
+
+
+class Model(dict):
+ def __init__(self, *args, **kwargs):
+ # Load the validator from the kwargs
+ #self.__dict__['validator'] = kwargs.pop('validator', self.default_validator)
+
+ # we overload setattr so set this manually
+ d = dict(*args, **kwargs)
+
+ try:
+ self.validator(d)
+ except exceptions.ValidationError as exc:
+ raise ValueError(str(exc))
+ else:
+ dict.__init__(self, d)
+
+ self.__dict__['changes'] = {}
+ self.__dict__['__original__'] = copy.deepcopy(d)
+
+ def __getattr__(self, key):
+ try:
+ return self.__getitem__(key)
+ except KeyError:
+ raise AttributeError(key)
+
+ def __setitem__(self, key, value):
+ mutation = dict(self.items())
+ mutation[key] = value
+ try:
+ self.validator(mutation)
+ except exceptions.ValidationError:
+ msg = "Unable to set '%s' to '%s'" % (key, value)
+ raise exceptions.InvalidOperation(msg)
+
+ dict.__setitem__(self, key, value)
+
+ self.__dict__['changes'][key] = value
+
+ def __setattr__(self, key, value):
+ self.__setitem__(key, value)
+
+ def clear(self):
+ raise exceptions.InvalidOperation()
+
+ def pop(self, key, default=None):
+ raise exceptions.InvalidOperation()
+
+ def popitem(self):
+ raise exceptions.InvalidOperation()
+
+ def __delitem__(self, key):
+ mutation = dict(self.items())
+ del mutation[key]
+ try:
+ self.validator(mutation)
+ except exceptions.ValidationError:
+ msg = "Unable to delete attribute '%s'" % (key)
+ raise exceptions.InvalidOperation(msg)
+
+ dict.__delitem__(self, key)
+
+ def __delattr__(self, key):
+ self.__delitem__(key)
+
+ # 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 exceptions.ValidationError as exc:
+ raise exceptions.InvalidOperation(str(exc))
+ dict.update(self, other)
+
+ def iteritems(self):
+ return copy.deepcopy(dict(self)).iteritems()
+
+ def items(self):
+ 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):
+ return copy.deepcopy(self.__dict__['changes'])
+
+ @property
+ def patch(self):
+ original = self.__dict__['__original__']
+ return jsonpatch.make_patch(original, dict(self)).to_string()
+
+ def default_validator(self, *args, **kwargs):
+ return True