Changed the way datas of complex types are stored. In previous versions, an

attribute was added to the type for each attribute, its name being the
attribute name prefixed with '_'.

Starting with this version, a single attribute _wsme_dataholder is added to
the instance.

The motivation behind this change is to avoid adding too many attributes to
the object and potential collisions with user attributes.
This commit is contained in:
Christophe de Vienne 2013-04-12 12:51:56 +02:00
parent c182b89425
commit 018594d262
3 changed files with 37 additions and 6 deletions

View File

@ -4,6 +4,16 @@ Changes
next next
---- ----
* Changed the way datas of complex types are stored. In previous versions, an
attribute was added to the type for each attribute, its name being the
attribute name prefixed with '_'.
Starting with this version, a single attribute _wsme_dataholder is added to
the instance.
The motivation behind this change is to avoid adding too many attributes to
the object.
* Add a special type 'HostRequest' that allow a function to ask for the host * Add a special type 'HostRequest' that allow a function to ask for the host
framework request object in its arguments. framework request object in its arguments.

View File

@ -88,7 +88,7 @@ class TestTypes(unittest.TestCase):
types.register_type(c) types.register_type(c)
assert c._wsme_attributes[0].key == 'a1' assert c._wsme_attributes[0].key == 'a1', c._wsme_attributes[0].key
assert c._wsme_attributes[1].key == 'a2' assert c._wsme_attributes[1].key == 'a2'
assert c._wsme_attributes[2].key == 'a3' assert c._wsme_attributes[2].key == 'a3'

View File

@ -297,7 +297,7 @@ class wsattr(object):
mandatoryvalue = wsattr(int, mandatory=True) mandatoryvalue = wsattr(int, mandatory=True)
named_value = wsattr(int, name='named.value') named_value = wsattr(int, name='named.value')
After inspection, the non-wsattr attributes will be replace, and After inspection, the non-wsattr attributes will be replaced, and
the above class will be equivalent to:: the above class will be equivalent to::
class MyComplexType(wsme.types.Base): class MyComplexType(wsme.types.Base):
@ -321,10 +321,21 @@ class wsattr(object):
self.complextype = None self.complextype = None
def _get_dataholder(self, instance):
dataholder = getattr(instance, '_wsme_dataholder', None)
if dataholder is None:
dataholder = instance._wsme_DataHolderClass()
instance._wsme_dataholder = dataholder
return dataholder
def __get__(self, instance, owner): def __get__(self, instance, owner):
if instance is None: if instance is None:
return self return self
return getattr(instance, '_' + self.key, self.default) return getattr(
self._get_dataholder(instance),
self.key,
self.default
)
def __set__(self, instance, value): def __set__(self, instance, value):
try: try:
@ -332,11 +343,12 @@ class wsattr(object):
except ValueError: except ValueError:
e = sys.exc_info()[1] e = sys.exc_info()[1]
raise ValueError("%s: %s" % (self.name, e)) raise ValueError("%s: %s" % (self.name, e))
dataholder = self._get_dataholder(instance)
if value is Unset: if value is Unset:
if hasattr(instance, '_' + self.key): if hasattr(dataholder, self.key):
delattr(instance, '_' + self.key) delattr(dataholder, self.key)
else: else:
setattr(instance, '_' + self.key, value) setattr(dataholder, self.key, value)
def __delete__(self, instance): def __delete__(self, instance):
self.__set__(instance, Unset) self.__set__(instance, Unset)
@ -456,6 +468,14 @@ def list_attributes(class_):
return class_._wsme_attributes return class_._wsme_attributes
def make_dataholder(class_):
class DataHolder(object):
__slots__ = [attr.key for attr in class_._wsme_attributes]
DataHolder.__name__ = class_.__name__ + 'DataHolder'
return DataHolder
class Registry(object): class Registry(object):
def __init__(self): def __init__(self):
self._complex_types = [] self._complex_types = []
@ -499,6 +519,7 @@ class Registry(object):
class_._wsme_attributes = None class_._wsme_attributes = None
class_._wsme_attributes = inspect_class(class_) class_._wsme_attributes = inspect_class(class_)
class_._wsme_DataHolderClass = make_dataholder(class_)
class_.__registry__ = self class_.__registry__ = self
self._complex_types.append(weakref.ref(class_)) self._complex_types.append(weakref.ref(class_))