Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 766FB200C8B for ; Mon, 22 May 2017 16:52:16 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 7533B160BA5; Mon, 22 May 2017 14:52:16 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 6AD4F160BD4 for ; Mon, 22 May 2017 16:52:15 +0200 (CEST) Received: (qmail 87032 invoked by uid 500); 22 May 2017 14:52:14 -0000 Mailing-List: contact dev-help@ariatosca.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ariatosca.incubator.apache.org Delivered-To: mailing list dev@ariatosca.incubator.apache.org Received: (qmail 87021 invoked by uid 99); 22 May 2017 14:52:14 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 May 2017 14:52:14 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 31D351AFAD6 for ; Mon, 22 May 2017 14:52:14 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.221 X-Spam-Level: X-Spam-Status: No, score=-4.221 tagged_above=-999 required=6.31 tests=[HK_RANDOM_FROM=0.001, KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id 8ZL_lQ5U0Xqr for ; Mon, 22 May 2017 14:52:11 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id 178E35FE1E for ; Mon, 22 May 2017 14:52:09 +0000 (UTC) Received: (qmail 85460 invoked by uid 99); 22 May 2017 14:52:07 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 May 2017 14:52:07 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id A51E6E00AF; Mon, 22 May 2017 14:52:07 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mxmrlv@apache.org To: dev@ariatosca.incubator.apache.org Date: Mon, 22 May 2017 14:52:07 -0000 Message-Id: <75e8fc492b354ea0ae8fd9ad0a3a420f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/4] incubator-ariatosca git commit: fixed dict archived-at: Mon, 22 May 2017 14:52:16 -0000 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 Authored: Mon May 22 14:28:44 2017 +0300 Committer: max-orlov 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_)