[pypy-svn] r78288 - in pypy/branch/set-object-cleanup/pypy/objspace/std: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Oct 26 13:41:10 CEST 2010
Author: arigo
Date: Tue Oct 26 13:41:08 2010
New Revision: 78288
Modified:
pypy/branch/set-object-cleanup/pypy/objspace/std/frozensettype.py
pypy/branch/set-object-cleanup/pypy/objspace/std/setobject.py
pypy/branch/set-object-cleanup/pypy/objspace/std/settype.py
pypy/branch/set-object-cleanup/pypy/objspace/std/test/test_setobject.py
Log:
Rewrite a bit sets. Tests pass, whatever that means.
Modified: pypy/branch/set-object-cleanup/pypy/objspace/std/frozensettype.py
==============================================================================
--- pypy/branch/set-object-cleanup/pypy/objspace/std/frozensettype.py (original)
+++ pypy/branch/set-object-cleanup/pypy/objspace/std/frozensettype.py Tue Oct 26 13:41:08 2010
@@ -39,13 +39,13 @@
def descr__frozenset__new__(space, w_frozensettype,
w_iterable=gateway.NoneNotWrapped):
from pypy.objspace.std.setobject import W_FrozensetObject
- from pypy.objspace.std.setobject import _is_frozenset_exact
+ from pypy.objspace.std.setobject import make_setdata_from_w_iterable
if (space.is_w(w_frozensettype, space.w_frozenset) and
- _is_frozenset_exact(w_iterable)):
+ w_iterable is not None and type(w_iterable) is W_FrozensetObject):
return w_iterable
w_obj = space.allocate_instance(W_FrozensetObject, w_frozensettype)
- W_FrozensetObject.__init__(w_obj, space, None)
-
+ data = make_setdata_from_w_iterable(space, w_iterable)
+ W_FrozensetObject.__init__(w_obj, space, data)
return w_obj
frozenset_typedef = StdTypeDef("frozenset",
Modified: pypy/branch/set-object-cleanup/pypy/objspace/std/setobject.py
==============================================================================
--- pypy/branch/set-object-cleanup/pypy/objspace/std/setobject.py (original)
+++ pypy/branch/set-object-cleanup/pypy/objspace/std/setobject.py Tue Oct 26 13:41:08 2010
@@ -21,11 +21,10 @@
return False
- def __init__(w_self, space, setdata=None):
- if setdata is None:
- w_self.setdata = r_dict(space.eq_w, space.hash_w)
- else:
- w_self.setdata = setdata.copy()
+ def __init__(w_self, space, setdata):
+ """Initialize the set by taking ownership of 'setdata'."""
+ assert setdata is not None
+ w_self.setdata = setdata
def __repr__(w_self):
"""representation for debugging purposes"""
@@ -33,6 +32,7 @@
return "<%s(%s)>" % (w_self.__class__.__name__, ', '.join(reprlist))
def _newobj(w_self, space, rdict_w=None):
+ """Make a new set or frozenset by taking ownership of 'rdict_w'."""
#return space.call(space.type(w_self),W_SetIterObject(rdict_w))
objtype = type(w_self)
if objtype is W_SetObject:
@@ -55,10 +55,7 @@
class W_FrozensetObject(W_BaseSetObject):
from pypy.objspace.std.frozensettype import frozenset_typedef as typedef
-
- def __init__(w_self, space, setdata):
- W_BaseSetObject.__init__(w_self, space, setdata)
- w_self.hash = -1
+ hash = 0
registerimplementation(W_BaseSetObject)
registerimplementation(W_SetObject)
@@ -109,8 +106,14 @@
# some helper functions
+def newset(space):
+ return r_dict(space.eq_w, space.hash_w)
+
def make_setdata_from_w_iterable(space, w_iterable=None):
- data = r_dict(space.eq_w, space.hash_w)
+ """Return a new r_dict with the content of w_iterable."""
+ if isinstance(w_iterable, W_BaseSetObject):
+ return w_iterable.setdata.copy()
+ data = newset(space)
if w_iterable is not None:
for w_item in space.listview(w_iterable):
data[w_item] = None
@@ -119,7 +122,7 @@
def _initialize_set(space, w_obj, w_iterable=None):
w_obj.setdata.clear()
if w_iterable is not None:
- w_obj.setdata.update(make_setdata_from_w_iterable(space, w_iterable))
+ w_obj.setdata = make_setdata_from_w_iterable(space, w_iterable)
def _convert_set_to_frozenset(space, w_obj):
if space.is_true(space.isinstance(w_obj, space.w_set)):
@@ -130,12 +133,6 @@
# helper functions for set operation on dicts
-def _is_frozenset_exact(w_obj):
- if (w_obj is not None) and (type(w_obj) is W_FrozensetObject):
- return True
- else:
- return False
-
def _is_eq(ld, rd):
if len(ld) != len(rd):
return False
@@ -144,66 +141,41 @@
return False
return True
-def _union_dict(ldict, rdict, isupdate):
- if isupdate:
- ld = ldict
- else:
- ld = ldict.copy()
- ld.update(rdict)
- return ld, rdict
-
-def _difference_dict(ldict, rdict, isupdate):
- if isupdate:
- ld = ldict
- else:
- ld = ldict.copy()
- del_list_w = []
+def _difference_dict(space, ld, rd):
+ result = newset(space)
for w_key in ld:
- if w_key in rdict:
- del_list_w.append(w_key)
- for w_key in del_list_w:
- del ld[w_key]
-
- return ld, rdict
-
-def _intersection_dict(ldict, rdict, isupdate):
- if isupdate:
- ld = ldict
- else:
- ld = ldict.copy()
- del_list_w = []
- for w_key in ld:
- if w_key not in rdict:
- del_list_w.append(w_key)
-
- for w_key in del_list_w:
- del ld[w_key]
-
- return ld, rdict
-
+ if w_key not in rd:
+ result[w_key] = None
+ return result
-def _symmetric_difference_dict(ldict, rdict, isupdate):
- if isupdate:
- ld = ldict
+def _difference_dict_update(space, ld, rd):
+ if ld is rd:
+ ld.clear() # for the case 'a.difference_update(a)'
else:
- ld = ldict.copy()
- del_list_w = []
- add_list_w = []
+ for w_key in rd:
+ try:
+ del ld[w_key]
+ except KeyError:
+ pass
+
+def _intersection_dict(space, ld, rd):
+ result = newset(space)
+ if len(ld) > len(rd):
+ ld, rd = rd, ld # loop over the smaller dict
for w_key in ld:
- if w_key in rdict:
- del_list_w.append(w_key)
+ if w_key in rd:
+ result[w_key] = None
+ return result
- for w_key in rdict:
+def _symmetric_difference_dict(space, ld, rd):
+ result = newset(space)
+ for w_key in ld:
+ if w_key not in rd:
+ result[w_key] = None
+ for w_key in rd:
if w_key not in ld:
- add_list_w.append(w_key)
-
- for w_key in del_list_w:
- del ld[w_key]
-
- for w_key in add_list_w:
- ld[w_key] = None
-
- return ld, rdict
+ result[w_key] = None
+ return result
def _issubset_dict(ldict, rdict):
if len(ldict) > len(rdict):
@@ -220,14 +192,13 @@
def set_update__Set_BaseSet(space, w_left, w_other):
# optimization only (the general case works too)
ld, rd = w_left.setdata, w_other.setdata
- new_ld, rd = _union_dict(ld, rd, True)
- return space.w_None
+ ld.update(rd)
def set_update__Set_ANY(space, w_left, w_other):
"""Update a set with the union of itself and another."""
- ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
- new_ld, rd = _union_dict(ld, rd, True)
- return space.w_None
+ ld = w_left.setdata
+ for w_item in space.listview(w_other):
+ ld[w_item] = None
def inplace_or__Set_Set(space, w_left, w_other):
set_update__Set_BaseSet(space, w_left, w_other)
@@ -241,25 +212,23 @@
This has no effect if the element is already present.
"""
w_left.setdata[w_other] = None
- return space.w_None
def set_copy__Set(space, w_set):
- return w_set._newobj(space,w_set.setdata)
+ return w_set._newobj(space, w_set.setdata.copy())
def frozenset_copy__Frozenset(space, w_left):
- if _is_frozenset_exact(w_left):
+ if type(w_left) is W_FrozensetObject:
return w_left
else:
- return set_copy__Set(space,w_left)
+ return set_copy__Set(space, w_left)
def set_clear__Set(space, w_left):
w_left.setdata.clear()
- return space.w_None
def set_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, rd = _difference_dict(ld, rd, False)
+ new_ld = _difference_dict(space, ld, rd)
return w_left._newobj(space, new_ld)
set_difference__Set_Frozenset = set_difference__Set_Set
@@ -272,7 +241,7 @@
def set_difference__Set_ANY(space, w_left, w_other):
ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
- new_ld, rd = _difference_dict(ld, rd, False)
+ new_ld = _difference_dict(space, ld, rd)
return w_left._newobj(space, new_ld)
frozenset_difference__Frozenset_ANY = set_difference__Set_ANY
@@ -281,15 +250,17 @@
def set_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, rd = _difference_dict(ld, rd, True)
- return space.w_None
+ _difference_dict_update(space, ld, rd)
set_difference_update__Set_Frozenset = set_difference_update__Set_Set
def set_difference_update__Set_ANY(space, w_left, w_other):
- ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
- new_ld, rd = _difference_dict(ld, rd, True)
- return space.w_None
+ ld = w_left.setdata
+ for w_key in space.listview(w_other):
+ try:
+ del ld[w_key]
+ except KeyError:
+ pass
def inplace_sub__Set_Set(space, w_left, w_other):
set_difference_update__Set_Set(space, w_left, w_other)
@@ -467,7 +438,7 @@
def hash__Frozenset(space, w_set):
multi = r_uint(1822399083) + r_uint(1822399083) + 1
- if w_set.hash != -1:
+ if w_set.hash != 0:
return space.wrap(w_set.hash)
hash = 1927868237
hash *= (len(w_set.setdata) + 1)
@@ -476,7 +447,7 @@
value = ((h ^ (h << 16) ^ 89869747) * multi)
hash = intmask(hash ^ value)
hash = hash * 69069 + 907133923
- if hash == -1:
+ if hash == 0:
hash = 590923713
hash = intmask(hash)
w_set.hash = hash
@@ -484,29 +455,31 @@
return space.wrap(hash)
def set_pop__Set(space, w_left):
- if len(w_left.setdata) == 0:
+ for w_key in w_left.setdata:
+ break
+ else:
raise OperationError(space.w_KeyError,
space.wrap('pop from an empty set'))
- w_keys = w_left.setdata.keys()
- w_value = w_keys[0]
- del w_left.setdata[w_value]
-
- return w_value
+ del w_left.setdata[w_key]
+ return w_key
def set_intersection__Set_Set(space, w_left, w_other):
# optimization only (the general case works too)
ld, rd = w_left.setdata, w_other.setdata
- new_ld, rd = _intersection_dict(ld, rd, False)
- return w_left._newobj(space,new_ld)
+ new_ld = _intersection_dict(space, ld, rd)
+ return w_left._newobj(space, new_ld)
set_intersection__Set_Frozenset = set_intersection__Set_Set
set_intersection__Frozenset_Frozenset = set_intersection__Set_Set
set_intersection__Frozenset_Set = set_intersection__Set_Set
def set_intersection__Set_ANY(space, w_left, w_other):
- ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
- new_ld, rd = _intersection_dict(ld, rd, False)
- return w_left._newobj(space,new_ld)
+ result = newset(space)
+ ld = w_left.setdata
+ for w_key in space.listview(w_other):
+ if w_key in ld:
+ result[w_key] = None
+ return w_left._newobj(space, result)
frozenset_intersection__Frozenset_ANY = set_intersection__Set_ANY
@@ -518,15 +491,18 @@
def set_intersection_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, rd = _intersection_dict(ld, rd, True)
- return space.w_None
+ new_ld = _intersection_dict(space, ld, rd)
+ w_left.setdata = new_ld
set_intersection_update__Set_Frozenset = set_intersection_update__Set_Set
def set_intersection_update__Set_ANY(space, w_left, w_other):
- ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
- new_ld, rd = _intersection_dict(ld, rd, True)
- return space.w_None
+ result = newset(space)
+ ld = w_left.setdata
+ for w_key in space.listview(w_other):
+ if w_key in ld:
+ result[w_key] = None
+ w_left.setdata = result
def inplace_and__Set_Set(space, w_left, w_other):
set_intersection_update__Set_Set(space, w_left, w_other)
@@ -537,7 +513,7 @@
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, rd = _symmetric_difference_dict(ld, rd, False)
+ new_ld = _symmetric_difference_dict(space, ld, rd)
return w_left._newobj(space, new_ld)
set_symmetric_difference__Set_Frozenset = set_symmetric_difference__Set_Set
@@ -553,7 +529,7 @@
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, rd = _symmetric_difference_dict(ld, rd, False)
+ new_ld = _symmetric_difference_dict(space, ld, rd)
return w_left._newobj(space, new_ld)
frozenset_symmetric_difference__Frozenset_ANY = \
@@ -562,16 +538,16 @@
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, rd = _symmetric_difference_dict(ld, rd, True)
- return space.w_None
+ new_ld = _symmetric_difference_dict(space, ld, rd)
+ w_left.setdata = new_ld
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, rd = _symmetric_difference_dict(ld, rd, True)
- return space.w_None
+ new_ld = _symmetric_difference_dict(space, ld, rd)
+ w_left.setdata = new_ld
def inplace_xor__Set_Set(space, w_left, w_other):
set_symmetric_difference_update__Set_Set(space, w_left, w_other)
@@ -582,8 +558,9 @@
def set_union__Set_Set(space, w_left, w_other):
# optimization only (the general case works too)
ld, rd = w_left.setdata, w_other.setdata
- new_ld, rd = _union_dict(ld, rd, False)
- return w_left._newobj(space, new_ld)
+ result = ld.copy()
+ result.update(rd)
+ return w_left._newobj(space, result)
set_union__Set_Frozenset = set_union__Set_Set
set_union__Frozenset_Set = set_union__Set_Set
@@ -595,9 +572,11 @@
def set_union__Set_ANY(space, w_left, w_other):
- ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
- new_ld, rd = _union_dict(ld, rd, False)
- return w_left._newobj(space, new_ld)
+ ld = w_left.setdata()
+ result = ld.copy()
+ for w_key in space.viewlist(w_other):
+ result[w_key] = None
+ return w_left._newobj(space, result)
frozenset_union__Frozenset_ANY = set_union__Set_ANY
@@ -629,15 +608,6 @@
init_defaults)
_initialize_set(space, w_set, w_iterable)
-def init__Frozenset(space, w_set, __args__):
- w_iterable, = __args__.parse_obj(
- None, 'set',
- init_signature,
- init_defaults)
- if w_set.hash == -1:
- _initialize_set(space, w_set, w_iterable)
- hash__Frozenset(space, w_set)
-
app = gateway.applevel("""
def setrepr(currently_in_repr, s):
'The app-level part of repr().'
Modified: pypy/branch/set-object-cleanup/pypy/objspace/std/settype.py
==============================================================================
--- pypy/branch/set-object-cleanup/pypy/objspace/std/settype.py (original)
+++ pypy/branch/set-object-cleanup/pypy/objspace/std/settype.py Tue Oct 26 13:41:08 2010
@@ -66,9 +66,9 @@
register_all(vars(), globals())
def descr__new__(space, w_settype, __args__):
- from pypy.objspace.std.setobject import W_SetObject
+ from pypy.objspace.std.setobject import W_SetObject, newset
w_obj = space.allocate_instance(W_SetObject, w_settype)
- W_SetObject.__init__(w_obj, space, None)
+ W_SetObject.__init__(w_obj, space, newset(space))
return w_obj
set_typedef = StdTypeDef("set",
Modified: pypy/branch/set-object-cleanup/pypy/objspace/std/test/test_setobject.py
==============================================================================
--- pypy/branch/set-object-cleanup/pypy/objspace/std/test/test_setobject.py (original)
+++ pypy/branch/set-object-cleanup/pypy/objspace/std/test/test_setobject.py Tue Oct 26 13:41:08 2010
@@ -10,6 +10,7 @@
import py.test
from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject
from pypy.objspace.std.setobject import _initialize_set
+from pypy.objspace.std.setobject import newset, make_setdata_from_w_iterable
from pypy.objspace.std.setobject import set_intersection__Set_Set
from pypy.objspace.std.setobject import set_intersection__Set_ANY
from pypy.objspace.std.setobject import eq__Set_Set
@@ -28,12 +29,12 @@
self.false = self.space.w_False
def test_and(self):
- s = W_SetObject(self.space, None)
+ s = W_SetObject(self.space, newset(self.space))
_initialize_set(self.space, s, self.word)
- t0 = W_SetObject(self.space, None)
+ t0 = W_SetObject(self.space, newset(self.space))
_initialize_set(self.space, t0, self.otherword)
- t1 = W_FrozensetObject(self.space, None)
- _initialize_set(self.space, t1, self.otherword)
+ t1 = W_FrozensetObject(self.space,
+ make_setdata_from_w_iterable(self.space, self.otherword))
r0 = set_intersection__Set_Set(self.space, s, t0)
r1 = set_intersection__Set_Set(self.space, s, t1)
assert eq__Set_Set(self.space, r0, r1) == self.true
@@ -41,9 +42,9 @@
assert eq__Set_Set(self.space, r0, sr) == self.true
def test_compare(self):
- s = W_SetObject(self.space, None)
+ s = W_SetObject(self.space, newset(self.space))
_initialize_set(self.space, s, self.word)
- t = W_SetObject(self.space, None)
+ t = W_SetObject(self.space, newset(self.space))
_initialize_set(self.space, t, self.word)
assert self.space.eq_w(s,t)
u = self.space.wrap(set('simsalabim'))
More information about the Pypy-commit
mailing list