diff --git a/doc/changes.rst b/doc/changes.rst index f44590b..fe5a45b 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -4,6 +4,16 @@ Changes 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 framework request object in its arguments. diff --git a/wsme/tests/test_types.py b/wsme/tests/test_types.py index d97ace0..6c5b4f1 100644 --- a/wsme/tests/test_types.py +++ b/wsme/tests/test_types.py @@ -88,7 +88,7 @@ class TestTypes(unittest.TestCase): 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[2].key == 'a3' diff --git a/wsme/types.py b/wsme/types.py index 88f0559..c69da0c 100644 --- a/wsme/types.py +++ b/wsme/types.py @@ -297,7 +297,7 @@ class wsattr(object): mandatoryvalue = wsattr(int, mandatory=True) 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:: class MyComplexType(wsme.types.Base): @@ -321,10 +321,21 @@ class wsattr(object): 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): if instance is None: return self - return getattr(instance, '_' + self.key, self.default) + return getattr( + self._get_dataholder(instance), + self.key, + self.default + ) def __set__(self, instance, value): try: @@ -332,11 +343,12 @@ class wsattr(object): except ValueError: e = sys.exc_info()[1] raise ValueError("%s: %s" % (self.name, e)) + dataholder = self._get_dataholder(instance) if value is Unset: - if hasattr(instance, '_' + self.key): - delattr(instance, '_' + self.key) + if hasattr(dataholder, self.key): + delattr(dataholder, self.key) else: - setattr(instance, '_' + self.key, value) + setattr(dataholder, self.key, value) def __delete__(self, instance): self.__set__(instance, Unset) @@ -456,6 +468,14 @@ def list_attributes(class_): 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): def __init__(self): self._complex_types = [] @@ -499,6 +519,7 @@ class Registry(object): class_._wsme_attributes = None class_._wsme_attributes = inspect_class(class_) + class_._wsme_DataHolderClass = make_dataholder(class_) class_.__registry__ = self self._complex_types.append(weakref.ref(class_))