Author: Lukas Diekmann <[email protected]>
Branch: set-strategies
Changeset: r49154:e1a4e3e28455
Date: 2011-05-13 14:25 +0200
http://bitbucket.org/pypy/pypy/changeset/e1a4e3e28455/
Log: added EmptySetStrategy + tests
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
@@ -120,6 +120,9 @@
def getdict_w(self):
return self.strategy.getdict_w(self)
+ def get_storage_copy(self):
+ return self.strategy.get_storage_copy(self)
+
def getkeys(self):
return self.strategy.getkeys(self)
@@ -183,6 +186,96 @@
def length(self, w_set):
raise NotImplementedError
+
+class EmptySetStrategy(SetStrategy):
+
+ cast_to_void_star, cast_from_void_star = rerased.new_erasing_pair("empty")
+ cast_to_void_star = staticmethod(cast_to_void_star)
+ cast_from_void_star = staticmethod(cast_from_void_star)
+
+ def get_empty_storage(self):
+ return self.cast_to_void_star(None)
+
+ def is_correct_type(self, w_key):
+ return False
+
+ def length(self, w_set):
+ return 0
+
+ def clear(self, w_set):
+ pass
+
+ def copy(self, w_set):
+ strategy = w_set.strategy
+ storage = self.cast_to_void_star(None)
+ clone = w_set.from_storage_and_strategy(storage, strategy)
+ return clone
+
+ def add(self, w_set, w_key):
+ #XXX switch to correct strategy later
+ w_set.switch_to_object_strategy(self.space)
+ w_set.add(w_key)
+
+ def delitem(self, w_set, w_item):
+ raise KeyError
+
+ def discard(self, w_set, w_item):
+ return False
+
+ def getdict_w(self, w_set):
+ return newset(self.space)
+
+ def get_storage_copy(self, w_set):
+ return w_set.sstorage
+
+ def getkeys(self, w_set):
+ return []
+
+ def has_key(self, w_set, w_key):
+ return False
+
+ def equals(self, w_set, w_other):
+ if w_other.strategy is self.space.fromcache(EmptySetStrategy):
+ return True
+ return False
+
+ def difference(self, w_set, w_other):
+ return w_set.copy()
+
+ def difference_update(self, w_set, w_other):
+ pass
+
+ def intersect(self, w_set, w_other):
+ return w_set.copy()
+
+ def intersect_update(self, w_set, w_other):
+ return w_set.copy()
+
+ def intersect_multiple(self, w_set, w_other):
+ return w_set.copy()
+
+ def intersect_multiple_update(self, w_set, w_other):
+ pass
+
+ def isdisjoint(self, w_set, w_other):
+ return True
+
+ def issuperset(self, w_set, w_other):
+ if self.space.unwrap(self.space.len(w_other)) == 0:
+ return True
+ return False
+
+ def symmetric_difference(self, w_set, w_other):
+ return w_other.copy()
+
+ def symmetric_difference_update(self, w_set, w_other):
+ w_set.strategy = w_other.strategy
+ w_set.sstorage = w_other.get_storage_copy()
+
+ def update(self, w_set, w_other):
+ w_set.switch_to_object_strategy(self.space)
+ w_set.update(w_other)
+
class AbstractUnwrappedSetStrategy(object):
__mixin__ = True
@@ -263,6 +356,11 @@
result[self.wrap(key)] = None
return result
+ def get_storage_copy(self, w_set):
+ d = self.cast_from_void_star(w_set.sstorage)
+ copy = self.cast_to_void_star(d.copy())
+ return copy
+
def getkeys(self, w_set):
keys = self.cast_from_void_star(w_set.sstorage).keys()
keys_w = [self.wrap(key) for key in keys]
@@ -282,6 +380,7 @@
return True
def difference(self, w_set, w_other):
+ #XXX return clone if other is Empty
result = w_set._newobj(self.space, None)
if not isinstance(w_other, W_BaseSetObject):
w_other = w_set._newobj(self.space, w_other)
@@ -292,6 +391,7 @@
return result
def difference_update(self, w_set, w_other):
+ #XXX do nothing if other is empty
if w_set is w_other:
w_set.clear() # for the case 'a.difference_update(a)'
else:
@@ -378,6 +478,7 @@
w_set.sstorage = result.sstorage
def issuperset(self, w_set, w_other):
+ #XXX other is empty is always True
if w_set.length() < self.space.unwrap(self.space.len(w_other)):
return False
for w_key in self.space.unpackiterable(w_other):
@@ -386,6 +487,7 @@
return True
def isdisjoint(self, w_set, w_other):
+ #XXX always True if other is empty
if w_set.length() > w_other.length():
return w_other.isdisjoint(w_set)
@@ -501,19 +603,25 @@
def set_strategy_and_setdata(space, w_set, w_iterable):
from pypy.objspace.std.intobject import W_IntObject
- if w_iterable is None:
- w_set.strategy = space.fromcache(ObjectSetStrategy) #XXX
EmptySetStrategy
- w_set.sstorage = w_set.strategy.get_empty_storage()
+ if w_iterable is None :
+ w_set.strategy = space.fromcache(EmptySetStrategy)
+ w_set.sstorage =
w_set.strategy.cast_to_void_star(None)#w_set.strategy.get_empty_storage()
return
if isinstance(w_iterable, W_BaseSetObject):
w_set.strategy = w_iterable.strategy
+ #XXX need to make copy here
w_set.sstorage = w_iterable.sstorage
return
if not isinstance(w_iterable, list):
w_iterable = space.listview(w_iterable)
+ if len(w_iterable) == 0:
+ w_set.strategy = space.fromcache(EmptySetStrategy)
+ w_set.sstorage = w_set.strategy.cast_to_void_star(None)
+ return
+
# check for integers
for item_w in w_iterable:
if type(item_w) is not W_IntObject:
@@ -844,6 +952,7 @@
return
def inplace_and__Set_Set(space, w_left, w_other):
+ #XXX why do we need to return here?
return w_left.intersect_update(w_other)
inplace_and__Set_Frozenset = inplace_and__Set_Set
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
@@ -458,3 +458,63 @@
s.difference_update(s)
assert s == set([])
+ def test_empty_empty(self):
+ assert set() == set([])
+
+ def test_empty_difference(self):
+ e = set()
+ x = set([1,2,3])
+ assert e.difference(x) == set()
+ assert x.difference(e) == x
+
+ e.difference_update(x)
+ assert e == set()
+ x.difference_update(e)
+ assert x == set([1,2,3])
+
+ assert e.symmetric_difference(x) == x
+ assert x.symmetric_difference(e) == x
+
+ e.symmetric_difference_update(e)
+ assert e == e
+ e.symmetric_difference_update(x)
+ assert e == x
+
+ x.symmetric_difference_update(set())
+ assert x == set([1,2,3])
+
+ def test_empty_intersect(self):
+ e = set()
+ x = set([1,2,3])
+ assert e.intersection(x) == e
+ assert x.intersection(e) == e
+ assert e & x == e
+ assert x & e == e
+
+ e.intersection_update(x)
+ assert e == set()
+ e &= x
+ assert e == set()
+ x.intersection_update(e)
+ assert x == set()
+
+ def test_empty_issuper(self):
+ e = set()
+ x = set([1,2,3])
+ assert e.issuperset(e) == True
+ assert e.issuperset(x) == False
+ assert x.issuperset(e) == True
+
+ def test_empty_issubset(self):
+ e = set()
+ x = set([1,2,3])
+ assert e.issubset(e) == True
+ assert e.issubset(x) == True
+ assert x.issubset(e) == False
+
+ def test_empty_isdisjoint(self):
+ e = set()
+ x = set([1,2,3])
+ assert e.isdisjoint(e) == True
+ assert e.isdisjoint(x) == True
+ assert x.isdisjoint(e) == True
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit