summaryrefslogtreecommitdiff
path: root/meta/jsonobject/properties.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/jsonobject/properties.py')
-rw-r--r--meta/jsonobject/properties.py155
1 files changed, 155 insertions, 0 deletions
diff --git a/meta/jsonobject/properties.py b/meta/jsonobject/properties.py
new file mode 100644
index 0000000000..05bba86da9
--- /dev/null
+++ b/meta/jsonobject/properties.py
@@ -0,0 +1,155 @@
+# DateTimeProperty, DateProperty, and TimeProperty
+# include code copied from couchdbkit
+from __future__ import absolute_import
+import sys
+import datetime
+import time
+import decimal
+from .base_properties import (
+ AbstractDateProperty,
+ AssertTypeProperty,
+ JsonContainerProperty,
+ JsonProperty,
+ DefaultProperty,
+)
+from .containers import JsonArray, JsonDict, JsonSet
+
+if sys.version > '3':
+ unicode = str
+ long = int
+
+
+class StringProperty(AssertTypeProperty):
+ _type = (unicode, str)
+
+ def selective_coerce(self, obj):
+ if isinstance(obj, str):
+ obj = unicode(obj)
+ return obj
+
+
+class BooleanProperty(AssertTypeProperty):
+ _type = bool
+
+
+class IntegerProperty(AssertTypeProperty):
+ _type = (int, long)
+
+
+class FloatProperty(AssertTypeProperty):
+ _type = float
+
+ def selective_coerce(self, obj):
+ if isinstance(obj, (int, long)):
+ obj = float(obj)
+ return obj
+
+
+class DecimalProperty(JsonProperty):
+
+ def wrap(self, obj):
+ return decimal.Decimal(obj)
+
+ def unwrap(self, obj):
+ if isinstance(obj, (int, long)):
+ obj = decimal.Decimal(obj)
+ elif isinstance(obj, float):
+ # python 2.6 doesn't allow a float to Decimal
+ obj = decimal.Decimal(unicode(obj))
+ assert isinstance(obj, decimal.Decimal)
+ return obj, unicode(obj)
+
+
+class DateProperty(AbstractDateProperty):
+ _type = datetime.date
+
+ def _wrap(self, value):
+ fmt = '%Y-%m-%d'
+ try:
+ return datetime.date(*time.strptime(value, fmt)[:3])
+ except ValueError as e:
+ raise ValueError('Invalid ISO date {0!r} [{1}]'.format(value, e))
+
+ def _unwrap(self, value):
+ return value, value.isoformat()
+
+
+class DateTimeProperty(AbstractDateProperty):
+ _type = datetime.datetime
+
+ def _wrap(self, value):
+ if not self.exact:
+ value = value.split('.', 1)[0] # strip out microseconds
+ value = value[0:19] # remove timezone
+ fmt = '%Y-%m-%dT%H:%M:%S'
+ else:
+ fmt = '%Y-%m-%dT%H:%M:%S.%fZ'
+ try:
+ return datetime.datetime.strptime(value, fmt)
+ except ValueError as e:
+ raise ValueError(
+ 'Invalid ISO date/time {0!r} [{1}]'.format(value, e))
+
+ def _unwrap(self, value):
+ if not self.exact:
+ value = value.replace(microsecond=0)
+ padding = ''
+ else:
+ padding = '' if value.microsecond else '.000000'
+ return value, value.isoformat() + padding + 'Z'
+
+
+class TimeProperty(AbstractDateProperty):
+ _type = datetime.time
+
+ def _wrap(self, value):
+ if not self.exact:
+ value = value.split('.', 1)[0] # strip out microseconds
+ fmt = '%H:%M:%S'
+ else:
+ fmt = '%H:%M:%S.%f'
+ try:
+ return datetime.time(*time.strptime(value, fmt)[3:6])
+ except ValueError as e:
+ raise ValueError('Invalid ISO time {0!r} [{1}]'.format(value, e))
+
+ def _unwrap(self, value):
+ if not self.exact:
+ value = value.replace(microsecond=0)
+ return value, value.isoformat()
+
+
+class ObjectProperty(JsonContainerProperty):
+ default = lambda self: self.item_type()
+
+ def wrap(self, obj, string_conversions=None):
+ return self.item_type.wrap(obj)
+
+ def unwrap(self, obj):
+ assert isinstance(obj, self.item_type), \
+ '{0} is not an instance of {1}'.format(obj, self.item_type)
+ return obj, obj._obj
+
+
+class ListProperty(JsonContainerProperty):
+ _type = default = list
+ container_class = JsonArray
+
+ def _update(self, container, extension):
+ container.extend(extension)
+
+
+class DictProperty(JsonContainerProperty):
+ _type = default = dict
+ container_class = JsonDict
+
+ def _update(self, container, extension):
+ container.update(extension)
+
+
+class SetProperty(JsonContainerProperty):
+ _type = default = set
+ container_class = JsonSet
+
+ def _update(self, container, extension):
+ container.update(extension)