Repository: incubator-ariatosca Updated Branches: refs/heads/ARIA-258-Convert-runtime-properties-to-attributes 5e5a25389 -> e2f5e25a8
wip Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/b8b7c704 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/b8b7c704 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/b8b7c704 Branch: refs/heads/ARIA-258-Convert-runtime-properties-to-attributes Commit: b8b7c704d23577d517bde1f2b03d797c85e7a803 Parents: 5e5a253 Author: max-orlov <ma...@gigaspaces.com> Authored: Thu May 18 16:31:24 2017 +0300 Committer: max-orlov <ma...@gigaspaces.com> Committed: Thu May 18 16:31:24 2017 +0300 ---------------------------------------------------------------------- aria/orchestrator/context/common.py | 157 +++++++--------------- tests/orchestrator/context/test_operation.py | 31 +++-- 2 files changed, 61 insertions(+), 127 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b8b7c704/aria/orchestrator/context/common.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py index d41566b..9f41071 100644 --- a/aria/orchestrator/context/common.py +++ b/aria/orchestrator/context/common.py @@ -203,147 +203,82 @@ class BaseContext(object): class _InstrumentedCollection(object): - def __init__(self, actor, attributes, model, nested=None): + def __init__(self, parent, model, nested=None): super(_InstrumentedCollection, self).__init__() - self._actor = actor - self._attributes = attributes + self._parent = parent self._model = model self._attr_cls = self._model.parameter.model_cls - self._nested = nested or [] + self._nested = nested or None - @property - def _nested_value(self): - current = self._attributes - for k in self._nested: - current = current[k] - return current.value if isinstance(current, self._attr_cls) else current - - def __getitem__(self, index): - value = self._nested_value[index] if self._nested else self._attributes[index].value + def __getitem__(self, key): + if isinstance(self._parent.get(key), self._attr_cls): + value = self._parent[key].value + else: + value = self._parent[key] if isinstance(value, list): - return _List(self._actor, - self._attributes, - self._model, - nested=self._nested + [index]) + return _InstrumentedList(self, self._model, key, _dict=value) elif isinstance(value, dict): - return _Dict(self._actor, - self._attributes, - self._model, - nested=self._nested + [index]) - elif isinstance(value, self._attr_cls): - return value.value - - return value - - def __delitem__(self, key): - del self._nested_value[key] + return _InstrumentedDict(self, self._model, key, _dict=value) + else: + return value - def __len__(self): - return len(self._nested_value) - def __nonzero__(self): - return bool(self._nested_value) +class _InstrumentedDict(_InstrumentedCollection, dict): + def __init__(self, *args, **kwargs): + dict_ = kwargs.pop('_dict', False) + super(_InstrumentedDict, self).__init__(*args, **kwargs) + if dict_: + dict.__init__(self, dict_ or {}) -class _Dict(_InstrumentedCollection, collections.MutableMapping): + def _set(self, key, value): + dict.__setitem__(self, key, value.value if isinstance(value, self._attr_cls) else value) def __setitem__(self, key, value): - if self._nested or key in self._attributes: - attribute = self._update_attr(key, value) - self._model.parameter.update(attribute) + self._set(key, value) + if self._nested is not None: + self._update_parent(self._nested, key, value) else: - attr = value if isinstance(value, self._attr_cls) else self._attr_cls.wrap(key, value) - self._attributes[key] = attr + if isinstance(value, self._attr_cls): + attr = value + else: + attr = self._attr_cls.wrap(key, value) + self._update_parent(key, key, attr) self._model.parameter.put(attr) - def _update_attr(self, key, value): - current = self._attributes - - # If this is nested, lets extract the Parameter itself - if self._nested: - attribute = current = current[self._nested[0]] - for k in self._nested[1:]: - current = current[k] - if isinstance(current, self._attr_cls): - current.value[key] = value - else: - current[key] = value - elif isinstance(current[key], self._attr_cls): - attribute = current[key] - attribute.value = value + def _update_parent(self, nested_key, key, value): + if isinstance(self._parent.get(self._nested), self._attr_cls): + self._parent[nested_key].value[key] = value else: - raise BaseException() - - # Since this a user defined parameter, this doesn't track changes. So we override the entire - # thing. - if isinstance(attribute.value, (dict, list)): - value = attribute.value.copy() - attribute.value.clear() - attribute.value = value - return attribute - - def keys(self): - dict_ = (self._nested_value.value - if isinstance(self._nested_value, self._attr_cls) - else self._nested_value) - for key in dict_.keys(): - yield key - - def values(self): - for val in self._nested_value.values(): - if isinstance(val, self._attr_cls): - yield val.value - else: - yield val - - def items(self): - for key in self._nested_value: - val = self._nested_value[key] - if isinstance(val, self._attr_cls): - yield key, val.value + if nested_key == key: + self._parent[nested_key] = value else: - yield key, val - - def __dict__(self): - return dict(item for item in self.items()) - - def __iter__(self): - for key in self._nested_value.keys(): - yield key - - def __copy__(self): - return dict((k, v) for k, v in self.items()) - - def __deepcopy__(self, *args, **kwargs): - return self.__copy__() - - def copy(self): - return self.__copy__() + self._parent[nested_key] = {key: value} def clear(self): - self._nested_value.clear() + self._parent.clear() -class _List(_InstrumentedCollection, collections.MutableSequence): +class _InstrumentedList(_InstrumentedCollection, collections.MutableSequence): def insert(self, index, value): - if self._nested: + if self._nested is not None: attribute = self._update_attr(index, value) self._model.parameter.update(attribute) - elif len(self._attributes) > index: - self._attributes[index].value = value - self._model.parameter.update(self._attributes[index]) + elif len(self._parent) > index: + self._parent[index].value = value + self._model.parameter.update(self._parent[index]) else: attr = value if isinstance(value, self._attr_cls) else self._attr_cls.wrap(index, value) - self._attributes.insert(index, attr) - self._model.parameter.put(self._attributes) + self._parent.insert(index, attr) + self._model.parameter.put(self._parent) def __setitem__(self, index, value): return self.insert(index, value) def _update_attr(self, index, value): - attribute = current = self._attributes[self._nested[0]] + attribute = current = self._parent[self._nested[0]] for i in self._nested[1:]: current = current[i] if isinstance(current, self._attr_cls): @@ -364,7 +299,7 @@ class _List(_InstrumentedCollection, collections.MutableSequence): return attribute def __eq__(self, other): - return self._nested_value.__eq__(other) + return self._parent.__eq__(other) class InstrumentCollection(object): @@ -389,8 +324,8 @@ class InstrumentCollection(object): self._actor = func(func_self, *args, **kwargs) field = getattr(self._actor, self._field_name) if isinstance(field, dict): - setattr(self, self._field_name, _Dict(self._actor, field, func_self.model)) + setattr(self, self._field_name, _InstrumentedDict(self._actor, field, func_self.model)) elif isinstance(field, list): - setattr(self, self._field_name, _List(self._actor, field, func_self.model)) + setattr(self, self._field_name, _InstrumentedList(self._actor, field, func_self.model)) return self return _wrapper http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b8b7c704/tests/orchestrator/context/test_operation.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py index 44823d1..a7656e5 100644 --- a/tests/orchestrator/context/test_operation.py +++ b/tests/orchestrator/context/test_operation.py @@ -525,7 +525,7 @@ class TestDict(object): return MockModel() def test_keys(self, model, actor): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) actor.attributes_dict.update( { 'key1': Parameter.wrap('key1', 'value1'), @@ -535,7 +535,7 @@ class TestDict(object): assert sorted(dict_.keys()) == sorted(['key1', 'key2']) def test_values(self, model, actor): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) actor.attributes_dict.update({ 'key1': Parameter.wrap('key1', 'value1'), 'key2': Parameter.wrap('key1', 'value2') @@ -543,7 +543,7 @@ class TestDict(object): assert sorted(dict_.values()) == sorted(['value1', 'value2']) def test_items(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) actor.attributes_dict.update({ 'key1': Parameter.wrap('key1', 'value1'), 'key2': Parameter.wrap('key1', 'value2') @@ -551,7 +551,7 @@ class TestDict(object): assert sorted(dict_.items()) == sorted([('key1', 'value1'), ('key2', 'value2')]) def test_iter(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) actor.attributes_dict.update({ 'key1': Parameter.wrap('key1', 'value1'), 'key2': Parameter.wrap('key1', 'value2') @@ -559,7 +559,7 @@ class TestDict(object): assert sorted(list(dict_)) == sorted(['key1', 'key2']) def test_bool(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) assert not dict_ actor.attributes_dict.update({ 'key1': Parameter.wrap('key1', 'value1'), @@ -568,29 +568,28 @@ class TestDict(object): assert dict_ def test_set_item(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor.attributes_dict, model) dict_['key1'] = Parameter.wrap('key1', 'value1') - assert 'key1' in dict_ - assert isinstance(dict_._attributes['key1'], Parameter) assert dict_['key1'] == 'value1' + assert isinstance(dict_._parent['key1'], Parameter) dict_['key1'] = {} dict_['key1']['inner_key'] = 'value2' - assert isinstance(dict_._attributes['key1'], Parameter) + assert isinstance(dict_._parent['key1'], Parameter) assert len(dict_) == 1 assert 'inner_key' in dict_['key1'] - assert isinstance(dict_['key1'], common._Dict) + assert isinstance(dict_['key1'], common._InstrumentedDict) assert dict_['key1']['inner_key'] == 'value2' def test_get_item(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) dict_['key1'] = Parameter.wrap('key1', 'value1') assert isinstance(dict_._attributes['key1'], Parameter) def test_update(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) dict_['key1'] = 'value1' new_dict = {'key2': 'value2'} @@ -604,7 +603,7 @@ class TestDict(object): assert new_dict['key1'] == dict_['key1'] def test_copy(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) dict_['key1'] = 'value1' new_dict = dict_.copy() @@ -616,7 +615,7 @@ class TestDict(object): assert dict_['key1'] == 'value2' def test_clear(self, actor, model): - dict_ = common._Dict(actor, actor.attributes_dict, model) + dict_ = common._InstrumentedDict(actor, actor.attributes_dict, model) dict_['key1'] = 'value1' dict_.clear() @@ -633,7 +632,7 @@ class TestList(object): return MockModel() def test_insert(self, model, actor): - list_ = common._List(actor, actor.attributes_list, model) + list_ = common._InstrumentedList(actor, actor.attributes_list, model) list_.append(Parameter.wrap('name', 'value1')) list_.append('value2') @@ -652,7 +651,7 @@ class TestList(object): assert list_[1] == 'new_value2' def test_insert_into_nested(self, model, actor): - list_ = common._List(actor, actor.attributes_list, model) + list_ = common._InstrumentedList(actor, actor.attributes_list, model) list_.append([]) list_[0].append('inner_item')