| Index: tools/telemetry/third_party/gsutilz/third_party/boto/boto/sdb/db/property.py
|
| diff --git a/tools/telemetry/third_party/gsutilz/third_party/boto/boto/sdb/db/property.py b/tools/telemetry/third_party/gsutilz/third_party/boto/boto/sdb/db/property.py
|
| deleted file mode 100644
|
| index 575aa8924dd7b0b57f18acf0f75448a23a3d299c..0000000000000000000000000000000000000000
|
| --- a/tools/telemetry/third_party/gsutilz/third_party/boto/boto/sdb/db/property.py
|
| +++ /dev/null
|
| @@ -1,704 +0,0 @@
|
| -# Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
|
| -#
|
| -# Permission is hereby granted, free of charge, to any person obtaining a
|
| -# copy of this software and associated documentation files (the
|
| -# "Software"), to deal in the Software without restriction, including
|
| -# without limitation the rights to use, copy, modify, merge, publish, dis-
|
| -# tribute, sublicense, and/or sell copies of the Software, and to permit
|
| -# persons to whom the Software is furnished to do so, subject to the fol-
|
| -# lowing conditions:
|
| -#
|
| -# The above copyright notice and this permission notice shall be included
|
| -# in all copies or substantial portions of the Software.
|
| -#
|
| -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
| -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
| -# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
| -# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
| -# IN THE SOFTWARE.
|
| -
|
| -import datetime
|
| -from boto.sdb.db.key import Key
|
| -from boto.utils import Password
|
| -from boto.sdb.db.query import Query
|
| -import re
|
| -import boto
|
| -import boto.s3.key
|
| -from boto.sdb.db.blob import Blob
|
| -from boto.compat import six, long_type
|
| -
|
| -
|
| -class Property(object):
|
| -
|
| - data_type = str
|
| - type_name = ''
|
| - name = ''
|
| - verbose_name = ''
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default=None,
|
| - required=False, validator=None, choices=None, unique=False):
|
| - self.verbose_name = verbose_name
|
| - self.name = name
|
| - self.default = default
|
| - self.required = required
|
| - self.validator = validator
|
| - self.choices = choices
|
| - if self.name:
|
| - self.slot_name = '_' + self.name
|
| - else:
|
| - self.slot_name = '_'
|
| - self.unique = unique
|
| -
|
| - def __get__(self, obj, objtype):
|
| - if obj:
|
| - obj.load()
|
| - return getattr(obj, self.slot_name)
|
| - else:
|
| - return None
|
| -
|
| - def __set__(self, obj, value):
|
| - self.validate(value)
|
| -
|
| - # Fire off any on_set functions
|
| - try:
|
| - if obj._loaded and hasattr(obj, "on_set_%s" % self.name):
|
| - fnc = getattr(obj, "on_set_%s" % self.name)
|
| - value = fnc(value)
|
| - except Exception:
|
| - boto.log.exception("Exception running on_set_%s" % self.name)
|
| -
|
| - setattr(obj, self.slot_name, value)
|
| -
|
| - def __property_config__(self, model_class, property_name):
|
| - self.model_class = model_class
|
| - self.name = property_name
|
| - self.slot_name = '_' + self.name
|
| -
|
| - def default_validator(self, value):
|
| - if isinstance(value, six.string_types) or value == self.default_value():
|
| - return
|
| - if not isinstance(value, self.data_type):
|
| - raise TypeError('Validation Error, %s.%s expecting %s, got %s' % (self.model_class.__name__, self.name, self.data_type, type(value)))
|
| -
|
| - def default_value(self):
|
| - return self.default
|
| -
|
| - def validate(self, value):
|
| - if self.required and value is None:
|
| - raise ValueError('%s is a required property' % self.name)
|
| - if self.choices and value and value not in self.choices:
|
| - raise ValueError('%s not a valid choice for %s.%s' % (value, self.model_class.__name__, self.name))
|
| - if self.validator:
|
| - self.validator(value)
|
| - else:
|
| - self.default_validator(value)
|
| - return value
|
| -
|
| - def empty(self, value):
|
| - return not value
|
| -
|
| - def get_value_for_datastore(self, model_instance):
|
| - return getattr(model_instance, self.name)
|
| -
|
| - def make_value_from_datastore(self, value):
|
| - return value
|
| -
|
| - def get_choices(self):
|
| - if callable(self.choices):
|
| - return self.choices()
|
| - return self.choices
|
| -
|
| -
|
| -def validate_string(value):
|
| - if value is None:
|
| - return
|
| - elif isinstance(value, six.string_types):
|
| - if len(value) > 1024:
|
| - raise ValueError('Length of value greater than maxlength')
|
| - else:
|
| - raise TypeError('Expecting String, got %s' % type(value))
|
| -
|
| -
|
| -class StringProperty(Property):
|
| -
|
| - type_name = 'String'
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default='',
|
| - required=False, validator=validate_string,
|
| - choices=None, unique=False):
|
| - super(StringProperty, self).__init__(verbose_name, name, default, required,
|
| - validator, choices, unique)
|
| -
|
| -
|
| -class TextProperty(Property):
|
| -
|
| - type_name = 'Text'
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default='',
|
| - required=False, validator=None, choices=None,
|
| - unique=False, max_length=None):
|
| - super(TextProperty, self).__init__(verbose_name, name, default, required,
|
| - validator, choices, unique)
|
| - self.max_length = max_length
|
| -
|
| - def validate(self, value):
|
| - value = super(TextProperty, self).validate(value)
|
| - if not isinstance(value, six.string_types):
|
| - raise TypeError('Expecting Text, got %s' % type(value))
|
| - if self.max_length and len(value) > self.max_length:
|
| - raise ValueError('Length of value greater than maxlength %s' % self.max_length)
|
| -
|
| -
|
| -class PasswordProperty(StringProperty):
|
| - """
|
| -
|
| - Hashed property whose original value can not be
|
| - retrieved, but still can be compared.
|
| -
|
| - Works by storing a hash of the original value instead
|
| - of the original value. Once that's done all that
|
| - can be retrieved is the hash.
|
| -
|
| - The comparison
|
| -
|
| - obj.password == 'foo'
|
| -
|
| - generates a hash of 'foo' and compares it to the
|
| - stored hash.
|
| -
|
| - Underlying data type for hashing, storing, and comparing
|
| - is boto.utils.Password. The default hash function is
|
| - defined there ( currently sha512 in most cases, md5
|
| - where sha512 is not available )
|
| -
|
| - It's unlikely you'll ever need to use a different hash
|
| - function, but if you do, you can control the behavior
|
| - in one of two ways:
|
| -
|
| - 1) Specifying hashfunc in PasswordProperty constructor
|
| -
|
| - import hashlib
|
| -
|
| - class MyModel(model):
|
| - password = PasswordProperty(hashfunc=hashlib.sha224)
|
| -
|
| - 2) Subclassing Password and PasswordProperty
|
| -
|
| - class SHA224Password(Password):
|
| - hashfunc=hashlib.sha224
|
| -
|
| - class SHA224PasswordProperty(PasswordProperty):
|
| - data_type=MyPassword
|
| - type_name="MyPassword"
|
| -
|
| - class MyModel(Model):
|
| - password = SHA224PasswordProperty()
|
| -
|
| - """
|
| - data_type = Password
|
| - type_name = 'Password'
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default='', required=False,
|
| - validator=None, choices=None, unique=False, hashfunc=None):
|
| -
|
| - """
|
| - The hashfunc parameter overrides the default hashfunc in boto.utils.Password.
|
| -
|
| - The remaining parameters are passed through to StringProperty.__init__"""
|
| -
|
| - super(PasswordProperty, self).__init__(verbose_name, name, default, required,
|
| - validator, choices, unique)
|
| - self.hashfunc = hashfunc
|
| -
|
| - def make_value_from_datastore(self, value):
|
| - p = self.data_type(value, hashfunc=self.hashfunc)
|
| - return p
|
| -
|
| - def get_value_for_datastore(self, model_instance):
|
| - value = super(PasswordProperty, self).get_value_for_datastore(model_instance)
|
| - if value and len(value):
|
| - return str(value)
|
| - else:
|
| - return None
|
| -
|
| - def __set__(self, obj, value):
|
| - if not isinstance(value, self.data_type):
|
| - p = self.data_type(hashfunc=self.hashfunc)
|
| - p.set(value)
|
| - value = p
|
| - super(PasswordProperty, self).__set__(obj, value)
|
| -
|
| - def __get__(self, obj, objtype):
|
| - return self.data_type(super(PasswordProperty, self).__get__(obj, objtype), hashfunc=self.hashfunc)
|
| -
|
| - def validate(self, value):
|
| - value = super(PasswordProperty, self).validate(value)
|
| - if isinstance(value, self.data_type):
|
| - if len(value) > 1024:
|
| - raise ValueError('Length of value greater than maxlength')
|
| - else:
|
| - raise TypeError('Expecting %s, got %s' % (type(self.data_type), type(value)))
|
| -
|
| -
|
| -class BlobProperty(Property):
|
| - data_type = Blob
|
| - type_name = "blob"
|
| -
|
| - def __set__(self, obj, value):
|
| - if value != self.default_value():
|
| - if not isinstance(value, Blob):
|
| - oldb = self.__get__(obj, type(obj))
|
| - id = None
|
| - if oldb:
|
| - id = oldb.id
|
| - b = Blob(value=value, id=id)
|
| - value = b
|
| - super(BlobProperty, self).__set__(obj, value)
|
| -
|
| -
|
| -class S3KeyProperty(Property):
|
| -
|
| - data_type = boto.s3.key.Key
|
| - type_name = 'S3Key'
|
| - validate_regex = "^s3:\/\/([^\/]*)\/(.*)$"
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default=None,
|
| - required=False, validator=None, choices=None, unique=False):
|
| - super(S3KeyProperty, self).__init__(verbose_name, name, default, required,
|
| - validator, choices, unique)
|
| -
|
| - def validate(self, value):
|
| - value = super(S3KeyProperty, self).validate(value)
|
| - if value == self.default_value() or value == str(self.default_value()):
|
| - return self.default_value()
|
| - if isinstance(value, self.data_type):
|
| - return
|
| - match = re.match(self.validate_regex, value)
|
| - if match:
|
| - return
|
| - raise TypeError('Validation Error, expecting %s, got %s' % (self.data_type, type(value)))
|
| -
|
| - def __get__(self, obj, objtype):
|
| - value = super(S3KeyProperty, self).__get__(obj, objtype)
|
| - if value:
|
| - if isinstance(value, self.data_type):
|
| - return value
|
| - match = re.match(self.validate_regex, value)
|
| - if match:
|
| - s3 = obj._manager.get_s3_connection()
|
| - bucket = s3.get_bucket(match.group(1), validate=False)
|
| - k = bucket.get_key(match.group(2))
|
| - if not k:
|
| - k = bucket.new_key(match.group(2))
|
| - k.set_contents_from_string("")
|
| - return k
|
| - else:
|
| - return value
|
| -
|
| - def get_value_for_datastore(self, model_instance):
|
| - value = super(S3KeyProperty, self).get_value_for_datastore(model_instance)
|
| - if value:
|
| - return "s3://%s/%s" % (value.bucket.name, value.name)
|
| - else:
|
| - return None
|
| -
|
| -
|
| -class IntegerProperty(Property):
|
| -
|
| - data_type = int
|
| - type_name = 'Integer'
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default=0, required=False,
|
| - validator=None, choices=None, unique=False, max=2147483647, min=-2147483648):
|
| - super(IntegerProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| - self.max = max
|
| - self.min = min
|
| -
|
| - def validate(self, value):
|
| - value = int(value)
|
| - value = super(IntegerProperty, self).validate(value)
|
| - if value > self.max:
|
| - raise ValueError('Maximum value is %d' % self.max)
|
| - if value < self.min:
|
| - raise ValueError('Minimum value is %d' % self.min)
|
| - return value
|
| -
|
| - def empty(self, value):
|
| - return value is None
|
| -
|
| - def __set__(self, obj, value):
|
| - if value == "" or value is None:
|
| - value = 0
|
| - return super(IntegerProperty, self).__set__(obj, value)
|
| -
|
| -
|
| -class LongProperty(Property):
|
| -
|
| - data_type = long_type
|
| - type_name = 'Long'
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default=0, required=False,
|
| - validator=None, choices=None, unique=False):
|
| - super(LongProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| -
|
| - def validate(self, value):
|
| - value = long_type(value)
|
| - value = super(LongProperty, self).validate(value)
|
| - min = -9223372036854775808
|
| - max = 9223372036854775807
|
| - if value > max:
|
| - raise ValueError('Maximum value is %d' % max)
|
| - if value < min:
|
| - raise ValueError('Minimum value is %d' % min)
|
| - return value
|
| -
|
| - def empty(self, value):
|
| - return value is None
|
| -
|
| -
|
| -class BooleanProperty(Property):
|
| -
|
| - data_type = bool
|
| - type_name = 'Boolean'
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default=False, required=False,
|
| - validator=None, choices=None, unique=False):
|
| - super(BooleanProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| -
|
| - def empty(self, value):
|
| - return value is None
|
| -
|
| -
|
| -class FloatProperty(Property):
|
| -
|
| - data_type = float
|
| - type_name = 'Float'
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default=0.0, required=False,
|
| - validator=None, choices=None, unique=False):
|
| - super(FloatProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| -
|
| - def validate(self, value):
|
| - value = float(value)
|
| - value = super(FloatProperty, self).validate(value)
|
| - return value
|
| -
|
| - def empty(self, value):
|
| - return value is None
|
| -
|
| -
|
| -class DateTimeProperty(Property):
|
| - """This class handles both the datetime.datetime object
|
| - And the datetime.date objects. It can return either one,
|
| - depending on the value stored in the database"""
|
| -
|
| - data_type = datetime.datetime
|
| - type_name = 'DateTime'
|
| -
|
| - def __init__(self, verbose_name=None, auto_now=False, auto_now_add=False, name=None,
|
| - default=None, required=False, validator=None, choices=None, unique=False):
|
| - super(DateTimeProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| - self.auto_now = auto_now
|
| - self.auto_now_add = auto_now_add
|
| -
|
| - def default_value(self):
|
| - if self.auto_now or self.auto_now_add:
|
| - return self.now()
|
| - return super(DateTimeProperty, self).default_value()
|
| -
|
| - def validate(self, value):
|
| - if value is None:
|
| - return
|
| - if isinstance(value, datetime.date):
|
| - return value
|
| - return super(DateTimeProperty, self).validate(value)
|
| -
|
| - def get_value_for_datastore(self, model_instance):
|
| - if self.auto_now:
|
| - setattr(model_instance, self.name, self.now())
|
| - return super(DateTimeProperty, self).get_value_for_datastore(model_instance)
|
| -
|
| - def now(self):
|
| - return datetime.datetime.utcnow()
|
| -
|
| -
|
| -class DateProperty(Property):
|
| -
|
| - data_type = datetime.date
|
| - type_name = 'Date'
|
| -
|
| - def __init__(self, verbose_name=None, auto_now=False, auto_now_add=False, name=None,
|
| - default=None, required=False, validator=None, choices=None, unique=False):
|
| - super(DateProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| - self.auto_now = auto_now
|
| - self.auto_now_add = auto_now_add
|
| -
|
| - def default_value(self):
|
| - if self.auto_now or self.auto_now_add:
|
| - return self.now()
|
| - return super(DateProperty, self).default_value()
|
| -
|
| - def validate(self, value):
|
| - value = super(DateProperty, self).validate(value)
|
| - if value is None:
|
| - return
|
| - if not isinstance(value, self.data_type):
|
| - raise TypeError('Validation Error, expecting %s, got %s' % (self.data_type, type(value)))
|
| -
|
| - def get_value_for_datastore(self, model_instance):
|
| - if self.auto_now:
|
| - setattr(model_instance, self.name, self.now())
|
| - val = super(DateProperty, self).get_value_for_datastore(model_instance)
|
| - if isinstance(val, datetime.datetime):
|
| - val = val.date()
|
| - return val
|
| -
|
| - def now(self):
|
| - return datetime.date.today()
|
| -
|
| -
|
| -class TimeProperty(Property):
|
| - data_type = datetime.time
|
| - type_name = 'Time'
|
| -
|
| - def __init__(self, verbose_name=None, name=None,
|
| - default=None, required=False, validator=None, choices=None, unique=False):
|
| - super(TimeProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| -
|
| - def validate(self, value):
|
| - value = super(TimeProperty, self).validate(value)
|
| - if value is None:
|
| - return
|
| - if not isinstance(value, self.data_type):
|
| - raise TypeError('Validation Error, expecting %s, got %s' % (self.data_type, type(value)))
|
| -
|
| -
|
| -class ReferenceProperty(Property):
|
| -
|
| - data_type = Key
|
| - type_name = 'Reference'
|
| -
|
| - def __init__(self, reference_class=None, collection_name=None,
|
| - verbose_name=None, name=None, default=None, required=False, validator=None, choices=None, unique=False):
|
| - super(ReferenceProperty, self).__init__(verbose_name, name, default, required, validator, choices, unique)
|
| - self.reference_class = reference_class
|
| - self.collection_name = collection_name
|
| -
|
| - def __get__(self, obj, objtype):
|
| - if obj:
|
| - value = getattr(obj, self.slot_name)
|
| - if value == self.default_value():
|
| - return value
|
| - # If the value is still the UUID for the referenced object, we need to create
|
| - # the object now that is the attribute has actually been accessed. This lazy
|
| - # instantiation saves unnecessary roundtrips to SimpleDB
|
| - if isinstance(value, six.string_types):
|
| - value = self.reference_class(value)
|
| - setattr(obj, self.name, value)
|
| - return value
|
| -
|
| - def __set__(self, obj, value):
|
| - """Don't allow this object to be associated to itself
|
| - This causes bad things to happen"""
|
| - if value is not None and (obj.id == value or (hasattr(value, "id") and obj.id == value.id)):
|
| - raise ValueError("Can not associate an object with itself!")
|
| - return super(ReferenceProperty, self).__set__(obj, value)
|
| -
|
| - def __property_config__(self, model_class, property_name):
|
| - super(ReferenceProperty, self).__property_config__(model_class, property_name)
|
| - if self.collection_name is None:
|
| - self.collection_name = '%s_%s_set' % (model_class.__name__.lower(), self.name)
|
| - if hasattr(self.reference_class, self.collection_name):
|
| - raise ValueError('duplicate property: %s' % self.collection_name)
|
| - setattr(self.reference_class, self.collection_name,
|
| - _ReverseReferenceProperty(model_class, property_name, self.collection_name))
|
| -
|
| - def check_uuid(self, value):
|
| - # This does a bit of hand waving to "type check" the string
|
| - t = value.split('-')
|
| - if len(t) != 5:
|
| - raise ValueError
|
| -
|
| - def check_instance(self, value):
|
| - try:
|
| - obj_lineage = value.get_lineage()
|
| - cls_lineage = self.reference_class.get_lineage()
|
| - if obj_lineage.startswith(cls_lineage):
|
| - return
|
| - raise TypeError('%s not instance of %s' % (obj_lineage, cls_lineage))
|
| - except:
|
| - raise ValueError('%s is not a Model' % value)
|
| -
|
| - def validate(self, value):
|
| - if self.validator:
|
| - self.validator(value)
|
| - if self.required and value is None:
|
| - raise ValueError('%s is a required property' % self.name)
|
| - if value == self.default_value():
|
| - return
|
| - if not isinstance(value, six.string_types):
|
| - self.check_instance(value)
|
| -
|
| -
|
| -class _ReverseReferenceProperty(Property):
|
| - data_type = Query
|
| - type_name = 'query'
|
| -
|
| - def __init__(self, model, prop, name):
|
| - self.__model = model
|
| - self.__property = prop
|
| - self.collection_name = prop
|
| - self.name = name
|
| - self.item_type = model
|
| -
|
| - def __get__(self, model_instance, model_class):
|
| - """Fetches collection of model instances of this collection property."""
|
| - if model_instance is not None:
|
| - query = Query(self.__model)
|
| - if isinstance(self.__property, list):
|
| - props = []
|
| - for prop in self.__property:
|
| - props.append("%s =" % prop)
|
| - return query.filter(props, model_instance)
|
| - else:
|
| - return query.filter(self.__property + ' =', model_instance)
|
| - else:
|
| - return self
|
| -
|
| - def __set__(self, model_instance, value):
|
| - """Not possible to set a new collection."""
|
| - raise ValueError('Virtual property is read-only')
|
| -
|
| -
|
| -class CalculatedProperty(Property):
|
| -
|
| - def __init__(self, verbose_name=None, name=None, default=None,
|
| - required=False, validator=None, choices=None,
|
| - calculated_type=int, unique=False, use_method=False):
|
| - super(CalculatedProperty, self).__init__(verbose_name, name, default, required,
|
| - validator, choices, unique)
|
| - self.calculated_type = calculated_type
|
| - self.use_method = use_method
|
| -
|
| - def __get__(self, obj, objtype):
|
| - value = self.default_value()
|
| - if obj:
|
| - try:
|
| - value = getattr(obj, self.slot_name)
|
| - if self.use_method:
|
| - value = value()
|
| - except AttributeError:
|
| - pass
|
| - return value
|
| -
|
| - def __set__(self, obj, value):
|
| - """Not possible to set a new AutoID."""
|
| - pass
|
| -
|
| - def _set_direct(self, obj, value):
|
| - if not self.use_method:
|
| - setattr(obj, self.slot_name, value)
|
| -
|
| - def get_value_for_datastore(self, model_instance):
|
| - if self.calculated_type in [str, int, bool]:
|
| - value = self.__get__(model_instance, model_instance.__class__)
|
| - return value
|
| - else:
|
| - return None
|
| -
|
| -
|
| -class ListProperty(Property):
|
| -
|
| - data_type = list
|
| - type_name = 'List'
|
| -
|
| - def __init__(self, item_type, verbose_name=None, name=None, default=None, **kwds):
|
| - if default is None:
|
| - default = []
|
| - self.item_type = item_type
|
| - super(ListProperty, self).__init__(verbose_name, name, default=default, required=True, **kwds)
|
| -
|
| - def validate(self, value):
|
| - if self.validator:
|
| - self.validator(value)
|
| - if value is not None:
|
| - if not isinstance(value, list):
|
| - value = [value]
|
| -
|
| - if self.item_type in six.integer_types:
|
| - item_type = six.integer_types
|
| - elif self.item_type in six.string_types:
|
| - item_type = six.string_types
|
| - else:
|
| - item_type = self.item_type
|
| -
|
| - for item in value:
|
| - if not isinstance(item, item_type):
|
| - if item_type == six.integer_types:
|
| - raise ValueError('Items in the %s list must all be integers.' % self.name)
|
| - else:
|
| - raise ValueError('Items in the %s list must all be %s instances' %
|
| - (self.name, self.item_type.__name__))
|
| - return value
|
| -
|
| - def empty(self, value):
|
| - return value is None
|
| -
|
| - def default_value(self):
|
| - return list(super(ListProperty, self).default_value())
|
| -
|
| - def __set__(self, obj, value):
|
| - """Override the set method to allow them to set the property to an instance of the item_type instead of requiring a list to be passed in"""
|
| - if self.item_type in six.integer_types:
|
| - item_type = six.integer_types
|
| - elif self.item_type in six.string_types:
|
| - item_type = six.string_types
|
| - else:
|
| - item_type = self.item_type
|
| - if isinstance(value, item_type):
|
| - value = [value]
|
| - elif value is None: # Override to allow them to set this to "None" to remove everything
|
| - value = []
|
| - return super(ListProperty, self).__set__(obj, value)
|
| -
|
| -
|
| -class MapProperty(Property):
|
| -
|
| - data_type = dict
|
| - type_name = 'Map'
|
| -
|
| - def __init__(self, item_type=str, verbose_name=None, name=None, default=None, **kwds):
|
| - if default is None:
|
| - default = {}
|
| - self.item_type = item_type
|
| - super(MapProperty, self).__init__(verbose_name, name, default=default, required=True, **kwds)
|
| -
|
| - def validate(self, value):
|
| - value = super(MapProperty, self).validate(value)
|
| - if value is not None:
|
| - if not isinstance(value, dict):
|
| - raise ValueError('Value must of type dict')
|
| -
|
| - if self.item_type in six.integer_types:
|
| - item_type = six.integer_types
|
| - elif self.item_type in six.string_types:
|
| - item_type = six.string_types
|
| - else:
|
| - item_type = self.item_type
|
| -
|
| - for key in value:
|
| - if not isinstance(value[key], item_type):
|
| - if item_type == six.integer_types:
|
| - raise ValueError('Values in the %s Map must all be integers.' % self.name)
|
| - else:
|
| - raise ValueError('Values in the %s Map must all be %s instances' %
|
| - (self.name, self.item_type.__name__))
|
| - return value
|
| -
|
| - def empty(self, value):
|
| - return value is None
|
| -
|
| - def default_value(self):
|
| - return {}
|
|
|