[pypy-svn] r24976 - in pypy/dist/pypy/objspace/std: . test
stephan at codespeak.net
stephan at codespeak.net
Fri Mar 24 19:51:29 CET 2006
Author: stephan
Date: Fri Mar 24 19:51:26 2006
New Revision: 24976
Added:
pypy/dist/pypy/objspace/std/setobject.py
pypy/dist/pypy/objspace/std/settype.py
Modified:
pypy/dist/pypy/objspace/std/model.py
pypy/dist/pypy/objspace/std/objspace.py
pypy/dist/pypy/objspace/std/test/helper.py
Log:
initial checkin of set/frozenset implementation for std objspace.
Since there are no tests yet (yes, I know), the WITHSET switch needs
to be set to 'True' in order to use native sets in pypy.
Modified: pypy/dist/pypy/objspace/std/model.py
==============================================================================
--- pypy/dist/pypy/objspace/std/model.py (original)
+++ pypy/dist/pypy/objspace/std/model.py Fri Mar 24 19:51:26 2006
@@ -9,6 +9,7 @@
import pypy.interpreter.special
WITHCOMPLEX = False
+WITHSET = False
class StdTypeModel:
@@ -22,6 +23,9 @@
from pypy.objspace.std.floattype import float_typedef
if WITHCOMPLEX:
from pypy.objspace.std.complextype import complex_typedef
+ if WITHSET:
+ from pypy.objspace.std.settype import set_typedef
+ from pypy.objspace.std.settype import frozenset_typedef
from pypy.objspace.std.tupletype import tuple_typedef
from pypy.objspace.std.listtype import list_typedef
from pypy.objspace.std.dicttype import dict_typedef
@@ -46,6 +50,8 @@
from pypy.objspace.std import floatobject
if WITHCOMPLEX:
from pypy.objspace.std import complexobject
+ if WITHSET:
+ from pypy.objspace.std import setobject
from pypy.objspace.std import tupleobject
from pypy.objspace.std import listobject
from pypy.objspace.std import dictobject
@@ -68,7 +74,6 @@
boolobject.W_BoolObject: [],
intobject.W_IntObject: [],
floatobject.W_FloatObject: [],
- #complexobject.W_ComplexObject: [],
tupleobject.W_TupleObject: [],
listobject.W_ListObject: [],
dictobject.W_DictObject: [],
@@ -87,6 +92,9 @@
}
if WITHCOMPLEX:
self.typeorder[complexobject.W_ComplexObject] = []
+ if WITHSET:
+ self.typeorder[setobject.W_SetObject] = []
+ self.typeorder[setobject.W_FrozensetObject] = []
for type in self.typeorder:
self.typeorder[type].append((type, None))
Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py (original)
+++ pypy/dist/pypy/objspace/std/objspace.py Fri Mar 24 19:51:26 2006
@@ -6,7 +6,8 @@
from pypy.interpreter.gateway import PyPyCacheDir
from pypy.tool.cache import Cache
from pypy.tool.sourcetools import func_with_new_name
-from pypy.objspace.std.model import W_Object, UnwrapError, WITHCOMPLEX
+from pypy.objspace.std.model import W_Object, UnwrapError
+from pypy.objspace.std.model import WITHCOMPLEX, WITHSET
from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.objspace.descroperation import DescrOperation
@@ -16,6 +17,19 @@
import os
import __builtin__
+#check for sets
+try:
+ s = set()
+ del s
+except NameError:
+ try:
+ from sets import Set as set
+ from sets import ImmutableSet as frozenset
+ except ImportError:
+ class DummySet(object):pass
+ set = DummySet
+ frozenset = DummySet
+
_registered_implementations = {}
def registerimplementation(implcls):
# hint to objspace.std.model to register the implementation class
@@ -285,15 +299,25 @@
return self.call_function(c,
self.wrap(x.real),
self.wrap(x.imag))
-
# SD disable for native complex
#if isinstance(x, complex):
# XXX is this right? YYY no, this is wrong right now (CT)
# ZZZ hum, seems necessary for complex literals in co_consts (AR)
- c = self.builtin.get('complex')
+ # c = self.builtin.get('complex')
# return self.call_function(c,
# self.wrap(x.real),
# self.wrap(x.imag))
+
+ if isinstance(x, set):
+ if WITHSET:
+ wrappeditems = [self.wrap(item) for item in x]
+ return W_SetObject(self, wrappeditems)
+
+ if isinstance(x, frozenset):
+ if WITHSET:
+ wrappeditems = [self.wrap(item) for item in x]
+ return W_FrozensetObject(self, wrappeditems)
+
if x is __builtin__.Ellipsis:
# '__builtin__.Ellipsis' avoids confusion with special.Ellipsis
return self.w_Ellipsis
@@ -340,6 +364,13 @@
def newcomplex(self, realval, imagval):
return W_ComplexObject(self, realval, imagval)
+ if WITHSET:
+ def newset(self, list_w):
+ return W_SetObject(self, list_w)
+
+ def newfrozenset(self, list_w):
+ return W_FrozensetObject(self, list_w)
+
def newlong(self, val): # val is an int
return W_LongObject.fromint(self, val)
Added: pypy/dist/pypy/objspace/std/setobject.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/setobject.py Fri Mar 24 19:51:26 2006
@@ -0,0 +1,161 @@
+from pypy.objspace.std.objspace import W_Object, OperationError
+from pypy.objspace.std.objspace import registerimplementation, register_all
+from pypy.objspace.std.model import WITHSET
+from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod
+from pypy.rpython.objectmodel import r_dict
+from pypy.interpreter import gateway
+
+def _set_init(w_self, space, wrappeditems):
+ W_Object.__init__(w_self, space)
+ w_self.data = data = r_dict(space.eq_w, space.hash_w)
+ if space.is_true(space.isinstance(wrappeditems, space.w_frozenset)):
+ data.update(wrappeditems.data)
+ elif space.is_true(space.isinstance(wrappeditems, space.w_set)):
+ data.update(wrappeditems.data)
+ else:
+ iterable_w = space.unpackiterable(wrappeditems)
+ for w_item in iterable_w:
+ w_self.data[w_item] = space.w_True
+
+
+class W_SetObject(W_Object):
+ from pypy.objspace.std.settype import set_typedef as typedef
+
+ def __init__(w_self, space, wrappeditems):
+ _set_init(w_self, space, wrappeditems)
+
+ def __repr__(w_self):
+ """representation for debugging purposes"""
+ reprlist = [repr(w_item) for w_item in w_self.data.keys()]
+ return "<%s(%s)>" % (w_self.__class__.__name__, ', '.join(reprlist))
+
+class W_FrozensetObject(W_Object):
+ from pypy.objspace.std.settype import frozenset_typedef as typedef
+
+ def __init__(w_self, space, wrappeditems):
+ _set_init(w_self, space, wrappeditems)
+
+registerimplementation(W_SetObject)
+registerimplementation(W_FrozensetObject)
+
+app = gateway.applevel("""
+ def and__Set_Set(s, o):
+ return s.intersection(o)
+
+ def ne__Set_Set(s, o):
+ return not s == o
+
+ def ge__Set_Set(s, o):
+ return s.issuperset(o)
+
+ def gt__Set_Set(s, o):
+ return s != o and s.issuperset(o)
+
+ def le__Set_Set(s, o):
+ return s.issubset(o)
+
+ def lt__Set_Set(s, o):
+ return s != o and s.issubset(o)
+
+ def cmp__Set_Set(s, o):
+ raise TypeError('cannot compare sets using cmp()')
+
+ def or__Set_Set(s, o):
+ return s.union(o)
+
+ def xor__Set_Set(s, o):
+ return s.symmetric_difference(o)
+
+ def repr__Set(s):
+ return 'set(%s)' % [x for x in s]
+
+ def repr__Frozenset(s):
+ return 'frozenset(%s)' % [x for x in s]
+
+ def sub__Set_Set(s, o):
+ return s.difference(o)
+
+ def isub__Set_Set(s, o):
+ s.difference_update(o)
+ return s
+
+ def ior__Set_Set(s, o):
+ s.update(o)
+ return s
+
+ def iand__Set_Set(s, o):
+ s.intersection_update(o)
+ return s
+
+ def ixor__Set_Set(s, o):
+ s.symmetric_difference_update(o)
+ return s
+
+""", filename=__file__)
+
+and__Set_Set = app.interphook("and__Set_Set")
+and__Set_Frozenset = and__Set_Set
+and__Frozenset_Set = and__Set_Set
+and__Frozenset_Frozenset = and__Set_Set
+
+ne__Set_Set = app.interphook("ne__Set_Set")
+ne__Set_Frozenset = ne__Set_Set
+ne__Frozenset_Set = ne__Set_Set
+ne__Frozenset_Frozenset = ne__Set_Set
+
+ge__Set_Set = app.interphook("ge__Set_Set")
+ge__Set_Frozenset = ge__Set_Set
+ge__Frozenset_Set = ge__Set_Set
+ge__Frozenset_Frozenset = ge__Set_Set
+
+le__Set_Set = app.interphook("le__Set_Set")
+le__Set_Frozenset = le__Set_Set
+le__Frozenset_Set = le__Set_Set
+le__Frozenset_Frozenset = le__Set_Set
+
+gt__Set_Set = app.interphook("gt__Set_Set")
+gt__Set_Frozenset = gt__Set_Set
+gt__Frozenset_Set = gt__Set_Set
+gt__Frozenset_Frozenset = gt__Set_Set
+
+lt__Set_Set = app.interphook("lt__Set_Set")
+lt__Set_Frozenset = lt__Set_Set
+lt__Frozenset_Set = lt__Set_Set
+lt__Frozenset_Frozenset = lt__Set_Set
+
+cmp__Set_Set = app.interphook("cmp__Set_Set")
+cmp__Set_Frozenset = cmp__Set_Set
+cmp__Frozenset_Frozenset = cmp__Set_Set
+cmp__Frozenset_Set = cmp__Set_Set
+
+or__Set_Set = app.interphook("or__Set_Set")
+or__Set_Frozenset = or__Set_Set
+or__Frozenset_Set = or__Set_Set
+or__Frozenset_Frozenset = or__Set_Set
+
+xor__Set_Set = app.interphook("xor__Set_Set")
+xor__Set_Frozenset = xor__Set_Set
+xor__Frozenset_Set = xor__Set_Set
+xor__Frozenset_Frozenset = xor__Set_Set
+
+repr__Set = app.interphook('repr__Set')
+repr__Frozenset = app.interphook('repr__Frozenset')
+
+sub__Set_Set = app.interphook('sub__Set_Set')
+sub__Set_Frozenset = sub__Set_Set
+sub__Frozenset_Set = sub__Set_Set
+sub__Frozenset_Frozenset = sub__Set_Set
+
+inplace_sub__Set_Set = app.interphook('isub__Set_Set')
+inplace_sub__Set_Frozenset = inplace_sub__Set_Set
+
+inplace_or__Set_Set = app.interphook('ior__Set_Set')
+inplace_or__Set_Frozenset = inplace_or__Set_Set
+
+inplace_and__Set_Set = app.interphook('iand__Set_Set')
+inplace_and__Set_Frozenset = inplace_and__Set_Set
+
+inplace_xor__Set_Set = app.interphook('ixor__Set_Set')
+inplace_xor__Set_Frozenset = inplace_xor__Set_Set
+
+register_all(vars())
Added: pypy/dist/pypy/objspace/std/settype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/settype.py Fri Mar 24 19:51:26 2006
@@ -0,0 +1,310 @@
+from pypy.interpreter.error import OperationError
+from pypy.objspace.std.objspace import register_all
+from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod
+from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod
+from pypy.interpreter.gateway import NoneNotWrapped
+from pypy.interpreter import gateway
+from pypy.objspace.std.model import WITHSET
+
+def descr__set__new__(space, w_settype, w_iterable=NoneNotWrapped):
+ from pypy.objspace.std.setobject import W_SetObject
+ if w_iterable is None:
+ w_iterable = space.newtuple([])
+ elif (space.is_w(w_settype, space.w_set) and
+ space.is_w(space.type(w_iterable), space.w_set)):
+ return w_iterable
+ w_obj = space.allocate_instance(W_SetObject, w_settype)
+ W_SetObject.__init__(w_obj, space, w_iterable)
+
+ return w_obj
+
+def descr__frozenset__new__(space, w_frozensettype, w_iterable=NoneNotWrapped):
+ from pypy.objspace.std.setobject import W_FrozensetObject
+ if w_iterable is None:
+ w_iterable = space.newtuple([])
+ elif (space.is_w(w_frozensettype, space.w_frozenset) and
+ space.is_w(space.type(w_iterable), space.w_frozenset)):
+ return w_iterable
+ w_obj = space.allocate_instance(W_FrozensetObject, w_frozensettype)
+ W_FrozensetObject.__init__(w_obj, space, w_iterable)
+
+ return w_obj
+
+# some helper functions
+
+def _extract_data_dict(space, w_left, w_right):
+ assert (space.is_true(space.isinstance(w_left, space.w_set)) or
+ space.is_true(space.isinstance(w_left, space.w_frozenset)))
+ if not (space.is_true(space.isinstance(w_right, space.w_set)) or
+ space.is_true(space.isinstance(w_right, space.w_frozenset))):
+ w_right = space.newset(w_right)
+
+ return w_left.data, w_right.data
+
+def _dict_to_set(space, rpdict):
+ return space.newset(space.newtuple(rpdict.keys()))
+
+def _dict_to_frozenset(space, rpdict):
+ return space.newfrozenset(space.newtuple(rpdict.keys()))
+
+# helper functions for set operation on dicts
+
+def _union_dict(space, ldict, rdict, isupdate):
+ if isupdate:
+ ld = ldict
+ else:
+ ld = ldict.copy()
+ ld.update(rdict)
+ return ld, rdict
+
+def _difference_dict(space, ldict, rdict, isupdate):
+ if isupdate:
+ ld = ldict
+ else:
+ ld = ldict.copy()
+ del_list_w = []
+ for w_key in ld.iterkeys():
+ 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(space, ldict, rdict, isupdate):
+ if isupdate:
+ ld = ldict
+ else:
+ ld = ldict.copy()
+ del_list_w = []
+ for w_key in ld.iterkeys():
+ 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
+
+
+def _symmetric_difference_dict(space, ldict, rdict, isupdate):
+ if isupdate:
+ ld = ldict
+ else:
+ ld = ldict.copy()
+ del_list_w = []
+ add_list_w = []
+ for w_key in ld.iterkeys():
+ if w_key in rdict:
+ del_list_w.append(w_key)
+
+ for w_key in rdict.iterkeys():
+ 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] = space.w_True
+
+ return ld, rdict
+
+def descr_update(space, w_self, w_iterable):
+ """Update a set with the union of itself and another."""
+ ld, rd = _extract_data_dict(space, w_self, w_iterable)
+ new_ld, rd = _union_dict(space, ld, rd, True)
+ return space.w_None
+
+def descr_add(space, w_self, w_other):
+ """Add an element to a set.
+
+ This has no effect if the element is already present.
+ """
+
+ w_self.data[w_other] = space.w_True
+
+def descr_copy_s(space, w_self):
+ return space.newset(w_self)
+
+def descr_copy_fs(space, w_self):
+ return space.newfrozenset(w_self)
+
+def descr_clear(space, w_self):
+ w_self.data.clear()
+
+def descr_difference_s(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _difference_dict(space, ld, rd, False)
+ return _dict_to_set(space, new_ld)
+
+def descr_difference_fs(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _difference_dict(space, ld, rd, False)
+ return _dict_to_frozenset(space, new_ld)
+
+
+def descr_difference_update(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _difference_dict(space, ld, rd, True)
+ return space.w_None
+
+def descr__set__eq__(space, w_self, w_other):
+ if space.is_w(w_self, w_other):
+ return space.w_True
+
+ if len(w_self.data) != len(w_other.data):
+ return space.w_False
+
+ for w_key in w_self.data.iterkeys():
+ if w_key not in w_other.data:
+ return space.w_False
+ return space.w_True
+
+def descr__set__contains__(space, w_self, w_other):
+ return space.newbool(w_other in w_self.data)
+
+def descr_issubset(space, w_self, w_other):
+ if space.is_w(w_self, w_other):
+ return space.w_True
+
+ if len(w_self.data) > len(w_other.data):
+ return space.w_False
+
+ for w_key in w_self.data:
+ if w_key not in w_other.data:
+ return space.w_False
+ return space.w_True
+
+def descr_issuperset(space, w_self, w_other):
+ if space.is_w(w_self, w_other):
+ return space.w_True
+
+ if len(w_self.data) < len(w_other.data):
+ return space.w_False
+
+ for w_key in w_other.data:
+ if w_key not in w_self.data:
+ return space.w_False
+ return space.w_True
+
+def descr_discard(space, w_self, w_item):
+ if w_item in w_self.data:
+ del w_self.data[w_item]
+
+def descr_remove(space, w_self, w_item):
+ try:
+ del w_self.data[w_item]
+ except KeyError:
+ raise OperationError(space.w_KeyError,
+ space.call_method(w_item,'__repr__'))
+
+def descr__set__hash__(space, w_self):
+ raise OperationError(space.w_TypeError,
+ space.wrap('set objects are unhashable'))
+
+def descr_pop(space, w_self):
+ if len(w_self.data) == 0:
+ raise OperationError(space.w_KeyError,
+ space.wrap('pop from an empty set'))
+ w_keys = w_self.data.keys()
+ w_value = w_keys[0]
+ del w_self.data[w_value]
+
+ return w_value
+
+def descr_intersection_s(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _intersection_dict(space, ld, rd, False)
+ return _dict_to_set(space, new_ld)
+
+def descr_intersection_fs(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _intersection_dict(space, ld, rd, False)
+ return _dict_to_frozenset(space, new_ld)
+
+def descr_intersection_update(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _intersection_dict(space, ld, rd, True)
+ return space.w_None
+
+def descr_symmetric_difference_s(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _symmetric_difference_dict(space, ld, rd, False)
+ return _dict_to_set(space, new_ld)
+
+def descr_symmetric_difference_fs(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _symmetric_difference_dict(space, ld, rd, False)
+ return _dict_to_frozenset(space, new_ld)
+
+def descr_symmetric_difference_update(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _symmetric_difference_dict(space, ld, rd, True)
+ return space.w_None
+
+def descr_union_s(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _union_dict(space, ld, rd, False)
+ return _dict_to_set(space, new_ld)
+
+def descr_union_fs(space, w_self, w_other):
+ ld, rd = _extract_data_dict(space, w_self, w_other)
+ new_ld, rd = _union_dict(space, ld, rd, False)
+ return _dict_to_frozenset(space, new_ld)
+
+def descr__set__len__(space, w_self):
+ return space.newint(len(w_self.data))
+
+def descr__set__iter__(space, w_self):
+ from pypy.objspace.std import iterobject
+ return iterobject.W_SeqIterObject(space,
+ space.newtuple(w_self.data.keys()))
+
+set_typedef = StdTypeDef("set",
+ __doc__ = """set(iterable) --> set object
+
+Build an unordered collection.""",
+ __new__ = newmethod(descr__set__new__),
+ __eq__ = newmethod(descr__set__eq__),
+ __contains__ = newmethod(descr__set__contains__),
+ __len__ = newmethod(descr__set__len__),
+ __iter__ = newmethod(descr__set__iter__),
+ __hash__ = newmethod(descr__set__hash__),
+ add = newmethod(descr_add),
+ clear = newmethod(descr_clear),
+ copy = newmethod(descr_copy_s),
+ difference = newmethod(descr_difference_s),
+ difference_update = newmethod(descr_difference_update),
+ discard = newmethod(descr_discard),
+ intersection = newmethod(descr_intersection_s),
+ intersection_update = newmethod(descr_intersection_update),
+ issubset = newmethod(descr_issubset),
+ issuperset = newmethod(descr_issuperset),
+ pop = newmethod(descr_pop),
+ remove = newmethod(descr_remove),
+ symmetric_difference = newmethod(descr_symmetric_difference_s),
+ symmetric_difference_update = newmethod(descr_symmetric_difference_update),
+ union = newmethod(descr_union_s),
+ update = newmethod(descr_update),
+ )
+
+#set_typedef.registermethods(globals())
+
+frozenset_typedef = StdTypeDef("frozenset",
+ __doc__ = """frozenset(iterable) --> frozenset object
+
+Build an immutable unordered collection.""",
+ __new__ = newmethod(descr__frozenset__new__),
+ __eq__ = newmethod(descr__set__eq__),
+ __contains__ = newmethod(descr__set__contains__),
+ __len__ = newmethod(descr__set__len__),
+ __iter__ = newmethod(descr__set__iter__),
+ copy = newmethod(descr_copy_fs),
+ difference = newmethod(descr_difference_fs),
+ intersection = newmethod(descr_intersection_fs),
+ issubset = newmethod(descr_issubset),
+ issuperset = newmethod(descr_issuperset),
+ symmetric_difference = newmethod(descr_symmetric_difference_fs),
+ union = newmethod(descr_union_fs),
+ )
Modified: pypy/dist/pypy/objspace/std/test/helper.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/helper.py (original)
+++ pypy/dist/pypy/objspace/std/test/helper.py Fri Mar 24 19:51:26 2006
@@ -1,5 +1,3 @@
-EPS = 1e-9
-
def raises(excp, func, *args):
try:
func(*args)
@@ -12,6 +10,13 @@
def assertNotEqual(a, b):
assert a != b
+def assertIs(a, b):
+ assert a is b
+
+# complex specific tests
+
+EPS = 1e-9
+
def assertAlmostEqual(a, b):
if isinstance(a, complex):
if isinstance(b, complex):
@@ -44,8 +49,6 @@
assertCloseAbs(x.real, y.real, eps)
assertCloseAbs(x.imag, y.imag, eps)
-def assertIs(a, b):
- assert a is b
def check_div(x, y):
"""Compute complex z=x*y, and check that z/x==y and z/y==x."""
More information about the Pypy-commit
mailing list