Author: Lukas Diekmann <lukas.diekm...@uni-duesseldorf.de> Branch: set-strategies Changeset: r49146:28ab4895a815 Date: 2011-05-10 11:59 +0200 http://bitbucket.org/pypy/pypy/changeset/28ab4895a815/
Log: added fixes and tests for symmetric_difference[_update] diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -113,6 +113,12 @@ def difference_update(self, w_other): return self.strategy.difference_update(self, w_other) + def symmetric_difference(self, w_other): + return self.strategy.symmetric_difference(self, w_other) + + def symmetric_difference_update(self, w_other): + return self.strategy.symmetric_difference_update(self, w_other) + def intersect(self, w_other): return self.strategy.intersect(self, w_other) @@ -289,6 +295,31 @@ except KeyError: pass + def symmetric_difference(self, w_set, w_other): + #XXX no wrapping when strategies are equal + result = w_set._newobj(self.space, newset(self.space)) + for w_key in w_set.getkeys(): + if not w_other.has_key(w_key): + result.add(w_key) + for w_key in w_other.getkeys(): + if not w_set.has_key(w_key): + result.add(w_key) + return result + + def symmetric_difference_update(self, w_set, w_other): + #XXX no wrapping when strategies are equal + newsetdata = newset(self.space) + for w_key in w_set.getkeys(): + if not w_other.has_key(w_key): + newsetdata[w_key] = None + for w_key in w_other.getkeys(): + if not w_set.has_key(w_key): + newsetdata[w_key] = None + + # do not switch strategy here if other items match + w_set.strategy = strategy = self.space.fromcache(ObjectSetStrategy) + w_set.sstorage = strategy.cast_to_void_star(newsetdata) + def intersect(self, w_set, w_other): if w_set.length() > w_other.length(): return w_other.intersect(w_set) @@ -811,9 +842,8 @@ def set_symmetric_difference__Set_Set(space, w_left, w_other): # optimization only (the general case works too) - ld, rd = w_left.setdata, w_other.setdata - new_ld = _symmetric_difference_dict(space, ld, rd) - return w_left._newobj(space, new_ld) + w_result = w_left.symmetric_difference(w_other) + return w_result set_symmetric_difference__Set_Frozenset = set_symmetric_difference__Set_Set set_symmetric_difference__Frozenset_Set = set_symmetric_difference__Set_Set @@ -827,26 +857,28 @@ def set_symmetric_difference__Set_ANY(space, w_left, w_other): - ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other) - new_ld = _symmetric_difference_dict(space, ld, rd) - return w_left._newobj(space, new_ld) + #XXX deal with iterables withouth turning them into sets + setdata = make_setdata_from_w_iterable(space, w_other) + w_other_as_set = w_left._newobj(space, setdata) + + w_result = w_left.symmetric_difference(w_other_as_set) + return w_result frozenset_symmetric_difference__Frozenset_ANY = \ set_symmetric_difference__Set_ANY def set_symmetric_difference_update__Set_Set(space, w_left, w_other): # optimization only (the general case works too) - ld, rd = w_left.setdata, w_other.setdata - new_ld = _symmetric_difference_dict(space, ld, rd) - w_left.setdata = new_ld + w_left.symmetric_difference_update(w_other) set_symmetric_difference_update__Set_Frozenset = \ set_symmetric_difference_update__Set_Set def set_symmetric_difference_update__Set_ANY(space, w_left, w_other): - ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other) - new_ld = _symmetric_difference_dict(space, ld, rd) - w_left.setdata = new_ld + #XXX deal with iterables withouth turning them into sets + setdata = make_setdata_from_w_iterable(space, w_other) + w_other_as_set = w_left._newobj(space, setdata) + w_left.symmetric_difference_update(w_other_as_set) def inplace_xor__Set_Set(space, w_left, w_other): set_symmetric_difference_update__Set_Set(space, w_left, w_other) diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -121,6 +121,33 @@ assert a == set() raises(KeyError, "a.pop()") + def test_symmetric_difference(self): + a = set([1,2,3]) + b = set([3,4,5]) + c = a.symmetric_difference(b) + assert c == set([1,2,4,5]) + + a = set([1,2,3]) + b = [3,4,5] + c = a.symmetric_difference(b) + assert c == set([1,2,4,5]) + + def test_symmetric_difference_update(self): + a = set([1,2,3]) + b = set([3,4,5]) + a.symmetric_difference_update(b) + assert a == set([1,2,4,5]) + + a = set([1,2,3]) + b = [3,4,5] + a.symmetric_difference_update(b) + assert a == set([1,2,4,5]) + + a = set([1,2,3]) + b = set([3,4,5]) + a ^= b + assert a == set([1,2,4,5]) + def test_subtype(self): class subset(set):pass a = subset() _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit