[pypy-commit] pypy set-strategies: added fixes and tests for symmetric_difference[_update]
l.diekmann
noreply at buildbot.pypy.org
Thu Nov 10 13:49:28 CET 2011
Author: Lukas Diekmann <lukas.diekmann at 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()
More information about the pypy-commit
mailing list