Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-258-Convert-runtime-properties-to-attributes ff3d9647d -> 
0b1a306f6


fixed dict


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/b2014b93
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/b2014b93
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/b2014b93

Branch: refs/heads/ARIA-258-Convert-runtime-properties-to-attributes
Commit: b2014b9341398a431703c1ff7cde3722b72c53bc
Parents: ff3d964
Author: max-orlov <ma...@gigaspaces.com>
Authored: Mon May 22 14:28:44 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Mon May 22 14:28:44 2017 +0300

----------------------------------------------------------------------
 aria/orchestrator/context/common.py          | 181 +++++++---------------
 tests/orchestrator/context/test_operation.py |  78 ++++++----
 2 files changed, 108 insertions(+), 151 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b2014b93/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py 
b/aria/orchestrator/context/common.py
index e1dbf5f..d85f284 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -202,146 +202,78 @@ class BaseContext(object):
         self.model.log._engine.dispose()
 
 
-class _InstrumentedCollection(dict):
-    def __init__(self, parent, model, actor=None, field_name=None, 
nested_key=None, **kwargs):
-        super(_InstrumentedCollection, self).__init__(**kwargs)
-
-        self._parent = parent
+class _InstrumentedDict(dict):
+    def __init__(self, model, parent, field_name=None, item_cls=None, 
seq=None, **kwargs):
         self._model = model
-        self._item_cls = self._model.parameter.model_cls
-        self._nested_key = nested_key
-
-        # Actor is not None only at the top level, where it should be updated
-        self._actor = actor
+        self._parent = parent
         self._field_name = field_name
-        if self._actor:
-            # Only the root parent has an _actor
-            self._init_from_parent()
-
-    def __getitem__(self, key):
-        if self._nested_key is None:
-            value = self._parent[key].value
-        elif isinstance(self, dict):
-            value = dict.__getitem__(self, key)
-        else:
-            raise BaseException()
-
-        if isinstance(value, (list, _InstrumentedList)):
-            return _InstrumentedList(self, self._model, nested_key=key, 
_list=value)
-        elif isinstance(value, dict):
-            return _InstrumentedDict(self, self._model, nested_key=key, 
**value)
-        else:
-            return value
-
-    def _set(self, i, y):
-        self._insert(i, y)
-        if self._nested_key is None:
-            nested_key = i
-            if not isinstance(y, self._item_cls):
-                y = self._item_cls.wrap(i, y)
-            self._model.parameter.put(y)
-        else:
-            nested_key = self._nested_key
-
-        self._update_parent(nested_key, i, y)
-        return y
-
-    def _init_from_parent(self):
-        for key, value in self._parent.items():
-            self._insert(key, value)
-
-    def _insert(self, key, value):
-        value = value.value if isinstance(value, self._item_cls) else value
-        super(_InstrumentedCollection, self).__setitem__(key, value)
-
-    def _update_parent(self, nested_key, key, value):
-        if isinstance(self._parent, _InstrumentedCollection):
-            self._parent._update_from_child(nested_key, {key: value})
-        else:
-            if self._nested_key is not None:
-                self._parent[nested_key] = {key: value}
-            else:
-                self._parent[key] = value
-
-    def _update_from_child(self, nested_key, value):
-        self[nested_key] = value
-        if isinstance(value, self._item_cls):
-            # We are the the top level
-            getattr(self._actor, self._field_name)[nested_key] = value
-            self._model.parameter.update(value)
+        self._item_cls = item_cls
+        self._load(seq, **kwargs)
 
-    def _update_actor(self, key, value):
-        raise NotImplementedError
+    def _load(self, seq=None, **kwargs):
+        seq = dict((key, value.value if isinstance(value, self._item_cls) else 
value)
+                   for key, value in (seq or {}).items())
+        super(_InstrumentedDict, self).__init__(seq, **kwargs)
 
-    def __setitem__(self, key, value):
-        value = self._set(key, value)
-
-        if self._actor:
-            self._update_actor(key, value)
-
-        if isinstance(value, self._item_cls):
-            self._model.parameter.update(value)
-
-
-class _InstrumentedDict(_InstrumentedCollection):
-    """
-    Dict implementation for instrumented collection
-    """
     def update(self, E=None, **F):
-        dict_ = E or {}
-        dict_.update(F.copy())
-        for key, value in dict_.items():
+        E = E or {}
+        for key, value in E.items():
+            self[key] = value
+        for key, value in F.items():
             self[key] = value
 
-    def clear(self):
-        self._parent.get(self._nested_key, {}).clear()
-        dict.clear(self)
-
-    def _update_actor(self, key, value):
-        getattr(self._actor, self._field_name)[key] = value
+    def __getitem__(self, key):
+        value = dict.__getitem__(self, key)
+        if isinstance(value, _InstrumentedDict):
+            return value
+        elif isinstance(value, dict):
+            return _InstrumentedDict(self._model, self, key, seq=value)
+        return value
 
+    def values(self):
+        return [self[key] for key in self.keys()]
 
-class _InstrumentedList(_InstrumentedDict):
-    """
-    List implementation of instrumented collection
-    """
-    def __init__(self, parent, *args, **kwargs):
-        list_ = kwargs.pop('_list', [])
-        if isinstance(parent, list):
-            parent = list(enumerate(parent))
-        super(_InstrumentedList, self).__init__(parent, *args, **kwargs)
-        for item in list_:
-            self.append(item)
+    def items(self):
+        return [(key, self[key]) for key in self.keys()]
 
     def __iter__(self):
-        for _, item in sorted(self.items(), cmp=lambda item: item[0]):
-            yield item
+        return (key for key in self.keys())
 
-    def _update_actor(self, key, value):
-        field = getattr(self._actor, self._field_name)
-        if key < len(field):
-            field[key] = value
-        else:
-            field.insert(key, value)
+    def _set(self, key, value):
+        if self._item_cls and isinstance(value, self._item_cls):
+            value = value.value
+        dict.__setitem__(self, key, value)
 
-    def _init_from_parent(self):
-        for item in self._parent:
-            self.append(item)
+    def __setitem__(self, key, value):
+        self._set(key, value)
+        def _set_parent(value):
+            if key in field and isinstance(field[key], self._item_cls):
+                if isinstance(field[key], dict):
+                    field[key].clear()
+                field[key].value = value
+            else:
+                field[key] = value
+            return field[key]
 
-    def append(self, item):
-        self._set(len(self), item)
+        if self._item_cls:
+            # We are at the top level
+            field = getattr(self._parent, self._field_name)
+            mapi = getattr(self._model, self._item_cls.__modelname__)
 
-    def _update_parent(self, nested_key, key, value):
-        if isinstance(self._parent, _InstrumentedCollection):
-            self._parent._update_from_child(nested_key, {key: value})
-        else:
-            if self._nested_key is not None:
-                self._parent[nested_key] = {key: value}
+            if key in field:
+                # Is this a existing field
+                value = _set_parent(value)
             else:
-                self._parent.insert(key, value)
+                if not isinstance(value, self._item_cls):
+                    # If it is not wrapped
+                    value = self._item_cls.wrap(key, value)
+                value = _set_parent(value)
 
-    def __repr__(self):
-        return repr(list(self))
+            mapi.update(value)
+        else:
+            dict.__setitem__(self, key, value)
+            # We are not at the top level
+            self._parent[self._field_name] = self
 
 
 class InstrumentCollection(object):
@@ -370,10 +302,9 @@ class InstrumentCollection(object):
             setattr(self, '_{0}'.format(self._field_name), field)
 
             # set instrumented value
-            inst_cls = _InstrumentedDict if isinstance(field, dict) else 
_InstrumentedList
             setattr(
                 self,
                 self._field_name,
-                inst_cls(field, func_self.model, actor=self._actor, 
field_name=self._field_name))
+                _InstrumentedDict(func_self.model, self._actor, 
field_name=self._field_name, item_cls=modeling.models.Parameter, seq=field))
             return self
         return _wrapper

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b2014b93/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py 
b/tests/orchestrator/context/test_operation.py
index 72b8efe..da78199 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -351,7 +351,7 @@ def test_attribute_consumption(ctx, executor, dataholder):
 
     source_node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_NAME)
 
-    inputs = {'attributes_dict': {'key': 'value'}}
+    inputs = {'dict_': {'key': 'value'}}
     interface = mock.models.create_interface(
         source_node.service,
         node_int_name,
@@ -489,8 +489,8 @@ def _test_plugin_workdir(ctx, filename, content):
 
 
 @operation
-def attribute_altering_operation(ctx, attributes_dict, **_):
-    ctx.node.attributes.update(attributes_dict)
+def attribute_altering_operation(ctx, dict_, **_):
+    ctx.node.attributes.update(dict_)
 
 
 @operation
@@ -502,7 +502,7 @@ def attribute_consuming_operation(ctx, holder_path, **_):
 
 class MockActor(object):
     def __init__(self):
-        self.attributes_dict = {}
+        self.dict_ = {}
         self.attributes_list = []
 
 
@@ -526,24 +526,25 @@ class TestDict(object):
 
     @pytest.fixture
     def dict_(self, actor, model):
-        return common._InstrumentedDict(
-            actor.attributes_dict, model, actor=actor, 
field_name='attributes_dict')
+        return common._InstrumentedDict(model, actor, 'dict_', 
item_cls=Parameter)
 
-    def test_keys(self, dict_):
+    def test_keys(self, actor, dict_):
         dict_.update(
             {
                 'key1': Parameter.wrap('key1', 'value1'),
                 'key2': Parameter.wrap('key2', 'value2')
             }
         )
-        assert sorted(dict_.keys()) == sorted(['key1', 'key2'])
+        assert sorted(dict_.keys()) == sorted(['key1', 'key2']) == 
sorted(actor.dict_.keys())
 
-    def test_values(self, dict_):
+    def test_values(self, actor, dict_):
         dict_.update({
             'key1': Parameter.wrap('key1', 'value1'),
             'key2': Parameter.wrap('key1', 'value2')
         })
-        assert sorted(dict_.values()) == sorted(['value1', 'value2'])
+        assert (sorted(dict_.values()) ==
+                sorted(['value1', 'value2']) ==
+                sorted(v.value for v in actor.dict_.values()))
 
     def test_items(self, dict_):
         dict_.update({
@@ -552,12 +553,12 @@ class TestDict(object):
         })
         assert sorted(dict_.items()) == sorted([('key1', 'value1'), ('key2', 
'value2')])
 
-    def test_iter(self, dict_):
+    def test_iter(self, actor, dict_):
         dict_.update({
             'key1': Parameter.wrap('key1', 'value1'),
             'key2': Parameter.wrap('key1', 'value2')
         })
-        assert sorted(list(dict_)) == sorted(['key1', 'key2'])
+        assert sorted(list(dict_)) == sorted(['key1', 'key2']) == 
sorted(actor.dict_.keys())
 
     def test_bool(self, dict_):
         assert not dict_
@@ -567,33 +568,58 @@ class TestDict(object):
         })
         assert dict_
 
-    def test_set_item(self, dict_):
+    def test_set_item(self, actor, dict_):
         dict_['key1'] = Parameter.wrap('key1', 'value1')
-        assert dict_['key1'] == 'value1'
-        assert isinstance(dict_._parent['key1'], Parameter)
+        assert dict_['key1'] == 'value1' == actor.dict_['key1'].value
+        assert isinstance(actor.dict_['key1'], Parameter)
 
-        dict_['key1'] = {}
-        dict_['key1']['inner_key'] = 'value2'
+    def test_nested(self, actor, dict_):
+        dict_['key'] = {}
+        assert isinstance(actor.dict_['key'], Parameter)
+        assert dict_['key'] == actor.dict_['key'].value == {}
 
-        assert isinstance(dict_._parent['key1'], Parameter)
+        dict_['key']['inner_key'] = 'value'
+
+        assert len(dict_) == 1
+        assert 'inner_key' in dict_['key']
+        assert dict_['key']['inner_key'] == 'value'
+        assert dict_['key'].keys() == ['inner_key']
+        assert dict_['key'].values() == ['value']
+        assert dict_['key'].items() == [('inner_key', 'value')]
+        assert isinstance(actor.dict_['key'], Parameter)
+        assert isinstance(dict_['key'], common._InstrumentedDict)
+
+        dict_['key'].update({'updated_key': 'updated_value'})
         assert len(dict_) == 1
-        assert 'inner_key' in dict_['key1']
-        assert isinstance(dict_['key1'], common._InstrumentedDict)
-        assert dict_['key1']['inner_key'] == 'value2'
+        assert 'updated_key' in dict_['key']
+        assert dict_['key']['updated_key'] == 'updated_value'
+        assert sorted(dict_['key'].keys()) == sorted(['inner_key', 
'updated_key'])
+        assert sorted(dict_['key'].values()) == sorted(['value', 
'updated_value'])
+        assert sorted(dict_['key'].items()) == sorted([('inner_key', 'value'),
+                                                       ('updated_key', 
'updated_value')])
+        assert isinstance(actor.dict_['key'], Parameter)
+        assert isinstance(dict_['key'], common._InstrumentedDict)
+
+        dict_.update({'key': 'override_value'})
+        assert len(dict_) == 1
+        assert 'key' in dict_
+        assert dict_['key'] == 'override_value'
+        assert len(actor.dict_) == 1
+        assert isinstance(actor.dict_['key'], Parameter)
+        assert actor.dict_['key'].value == 'override_value'
 
-    def test_get_item(self, dict_):
+    def test_get_item(self, actor,dict_):
         dict_['key1'] = Parameter.wrap('key1', 'value1')
+        assert isinstance(actor.dict_['key1'], Parameter)
 
-        assert isinstance(dict_._parent['key1'], Parameter)
-
-    def test_update(self, dict_):
+    def test_update(self, actor, dict_):
         dict_['key1'] = 'value1'
 
         new_dict = {'key2': 'value2'}
         dict_.update(new_dict)
         assert len(dict_) == 2
         assert dict_['key2'] == 'value2'
-        assert isinstance(dict_._parent['key2'], Parameter)
+        assert isinstance(actor.dict_['key2'], Parameter)
 
         new_dict = {}
         new_dict.update(dict_)

Reply via email to