Merge "Remove deep dependency from muranoapi"

This commit is contained in:
Jenkins 2014-04-14 13:45:30 +00:00 committed by Gerrit Code Review
commit 246a35b6f9
4 changed files with 164 additions and 3 deletions

View File

@ -144,6 +144,60 @@ class TraverseHelper(object):
raise ValueError(_('Source object or path is malformed'))
def is_different(obj1, obj2):
"""
Stripped-down version of deep.diff comparator
Compares arbitrary nested objects, handles circular links, but doesn't
point to the first difference as deep.diff does.
"""
class Difference(Exception):
pass
def is_in(o, st):
for _o in st:
if o is _o:
return True
return False
def rec(o1, o2, stack1=(), stack2=()):
if is_in(o1, stack1) and is_in(o2, stack2):
# circular reference detected - break the loop
return
elif is_in(o1, stack1):
raise Difference()
else:
stack1 += (o1,)
stack2 += (o2,)
if o1 is o2:
return
elif type(o1) != type(o2):
raise Difference()
elif isinstance(o1, dict):
# check for keys inequality
rec(o1.keys(), o2.keys(), stack1, stack2)
for key in o1.keys():
rec(o1[key], o2[key], stack1, stack2)
elif isinstance(o1, (list, tuple, set)):
if len(o1) != len(o2):
raise Difference()
else:
for _o1, _o2 in zip(o1, o2):
rec(_o1, _o2, stack1, stack2)
elif hasattr(o1, '__dict__'):
return rec(o1.__dict__, o2.__dict__, stack1, stack2)
elif o1 != o2:
raise Difference()
try:
rec(obj1, obj2)
except Difference:
return True
else:
return False
def build_entity_map(value):
def build_entity_map_recursive(value, id_map):
if isinstance(value, types.DictionaryType):

View File

@ -18,10 +18,10 @@ import sys
import types
import uuid
import deep
import eventlet.greenpool
import yaql.expressions
from muranoapi.common import utils
import muranoapi.dsl.murano_object
import muranoapi.dsl.yaql_expression as yaql_expression
@ -97,7 +97,7 @@ def merge_lists(list1, list2):
for item in list1 + list2:
exists = False
for old_item in result:
if deep.diff(item, old_item) is None:
if not utils.is_different(item, old_item):
exists = True
break
if not exists:

View File

@ -0,0 +1,108 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import unittest2 as unittest
from muranoapi.common import utils
class IsDifferentTests(unittest.TestCase):
def test_equal_dicts(self):
obj1 = {'first': 10, 'second': 12}
obj2 = {'second': 12, 'first': 10}
comparison = utils.is_different(obj1, obj2)
self.assertFalse(comparison)
def test_different_dicts(self):
obj1 = {'first': 10, 'second': 11}
obj2 = {'first': 10, 'second': 12}
comparison = utils.is_different(obj1, obj2)
self.assertTrue(comparison)
def test_different_objs(self):
class Cls1(object):
a = 10
class Cls2(object):
b = 20
obj1 = Cls1()
obj2 = Cls2()
obj3 = Cls1()
obj3.a = {'one': 14, 'two': [(1, 2, 3), 'more']}
comparison1 = utils.is_different(obj1, obj2)
comparison2 = utils.is_different(obj1, obj3)
self.assertTrue(comparison1)
self.assertTrue(comparison2)
def test_equal_objs(self):
class Cls(object):
pass
obj1 = Cls()
obj2 = Cls()
obj1.a = {'one': 14, 'two': [(1, 2, 3), 'more']}
obj2.a = {'one': 14, 'two': [(1, 2, 3), 'more']}
comparison = utils.is_different(obj1, obj2)
self.assertFalse(comparison)
def test_equal_circular_objs(self):
class Cls(object):
pass
lst1 = [1, 2, 3]
lst2 = [1, 2, 3]
lst1.append(lst1)
lst2.append(lst2)
dct1 = {'one': 10, 'two': lst1}
dct2 = {'one': 10, 'two': lst1}
obj1 = Cls()
obj2 = Cls()
obj1.a = obj2.a = 10
obj1.self = obj1
obj2.self = obj2
comparison = utils.is_different(lst1, lst2)
comparison2 = utils.is_different(dct1, dct2)
comparison3 = utils.is_different(obj1, obj2)
self.assertFalse(comparison)
self.assertFalse(comparison2)
self.assertFalse(comparison3)
def test_different_circular_objs(self):
class Cls(object):
pass
obj1 = Cls()
obj2 = Cls()
obj1.self = obj1
obj2.self = {'self': obj2}
dct1 = {'one': [1, 2], 'three': 10}
dct2 = {'one': [1, 2]}
dct1['self'] = dct1
dct2['self'] = dct2
comparison = utils.is_different(obj1, obj2)
comparison1 = utils.is_different(dct1, dct2)
self.assertTrue(comparison)
self.assertTrue(comparison1)

View File

@ -38,4 +38,3 @@ oslo.messaging>=1.3.0a9
# not listed in global requirements
yaql>=0.2.2,<0.3
deep