[pypy-svn] r29824 - in pypy/branch/objspace-config-cleanup/pypy/objspace/std: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sat Jul 8 15:51:42 CEST 2006


Author: cfbolz
Date: Sat Jul  8 15:51:36 2006
New Revision: 29824

Added:
   pypy/branch/objspace-config-cleanup/pypy/objspace/std/dictstrobject.py
   pypy/branch/objspace-config-cleanup/pypy/objspace/std/test/test_dictstrobject.py
Modified:
   pypy/branch/objspace-config-cleanup/pypy/objspace/std/dicttype.py
   pypy/branch/objspace-config-cleanup/pypy/objspace/std/marshal_impl.py
   pypy/branch/objspace-config-cleanup/pypy/objspace/std/model.py
   pypy/branch/objspace-config-cleanup/pypy/objspace/std/objspace.py
   pypy/branch/objspace-config-cleanup/pypy/objspace/std/test/test_dictobject.py
Log:
(cfbolz, fijal, xoraxax): add dict implementation optimized for string keys.
tests are still failing, though, the space cannot be instantiated


Added: pypy/branch/objspace-config-cleanup/pypy/objspace/std/dictstrobject.py
==============================================================================
--- (empty file)
+++ pypy/branch/objspace-config-cleanup/pypy/objspace/std/dictstrobject.py	Sat Jul  8 15:51:36 2006
@@ -0,0 +1,478 @@
+
+from pypy.objspace.std.objspace import *
+from pypy.interpreter import gateway
+
+from pypy.rpython.objectmodel import r_dict
+
+class W_DictStrObject(W_Object):
+    from pypy.objspace.std.dicttype import dict_typedef as typedef
+
+    def __init__(w_self, space, w_otherdict=None):
+        w_self.space = space
+        if w_otherdict is None:
+            w_self.content = None
+            w_self.content_str = {}
+        else:
+            if w_otherdict.content is None:
+                w_self.content = None
+                w_self.content_str = w_otherdict.content_str.copy()
+            else:
+                w_self.content = w_otherdict.content.copy()
+                w_self.content_str = None
+
+    def initialize_content(w_self, list_pairs_w): # YYY
+        for w_k, w_v in list_pairs_w:
+            w_self.setitem(w_k, w_v)
+
+    def getitem(w_dict, w_lookup):
+        space = w_dict.space
+        if w_dict.content is None:
+            if space.is_w(space.type(w_lookup), space.w_str):
+                return w_dict.content_str[space.str_w(w_lookup)]
+            else:
+                w_dict.str2object()
+        return w_dict.content[w_lookup]
+
+    def get(w_dict, w_lookup):
+        space = w_dict.space
+        if w_dict.content is None:
+            if space.is_w(space.type(w_lookup), space.w_str):
+                return w_dict.content_str.get(space.str_w(w_lookup), None)
+            else:
+                w_dict.str2object()
+        return w_dict.content.get(w_lookup, None)
+
+    
+    def setitem(w_self, w_k, w_v):
+        space = w_self.space
+        if w_self.content is None:
+            if space.is_w(space.type(w_k), space.w_str):
+                w_self.content_str[space.str_w(w_k)] = w_v
+            else:
+                w_self.str2object()
+                w_self.content[w_k] = w_v
+        else:
+            w_self.content[w_k] = w_v
+
+    def str2object(w_self):
+        """ Moves all items in the content_str dict to content. """
+        assert w_self.content_str is not None and w_self.content is None
+        
+        # create a new r_dict
+        w_self.content = r_dict(w_self.space.eq_w, w_self.space.hash_w)
+        for k, w_v in w_self.content_str.items():
+            w_self.content[w_self.space.wrap(k)] = w_v
+        w_self.content_str = None
+        
+    def __repr__(w_self):
+        """ representation for debugging purposes """
+        return "%s(%s,%s)" % (w_self.__class__.__name__, w_self.content, w_self.content_str)
+
+    def unwrap(w_dict, space): # YYY
+        result = {}
+        if w_dict.content_str is None:
+            for w_key, w_value in w_dict.content.items():
+                # generic mixed types unwrap
+                result[space.unwrap(w_key)] = space.unwrap(w_value)
+        else:
+            for key, w_value in w_dict.content_str.items():
+                # generic mixed types unwrap
+                result[key] = space.unwrap(w_value)
+        return result
+    
+    def len(w_dict):
+        if w_dict.content is not None:
+            return len(w_dict.content)
+        return len(w_dict.content_str)
+
+registerimplementation(W_DictStrObject)
+
+
+def init__DictStr(space, w_dict, __args__):
+    w_src, w_kwds = __args__.parse('dict',
+                          (['seq_or_map'], None, 'kwargs'), # signature
+                          [W_DictStrObject(space)])            # default argument
+    if w_dict.content is None:
+        w_dict.content_str.clear()
+    else:
+        w_dict.content.clear()
+
+    try:
+        space.getattr(w_src, space.wrap("keys"))
+    except OperationError:
+        list_of_w_pairs = space.unpackiterable(w_src)
+        for w_pair in list_of_w_pairs:
+            pair = space.unpackiterable(w_pair)
+            if len(pair)!=2:
+                raise OperationError(space.w_ValueError,
+                             space.wrap("dict() takes a sequence of pairs"))
+            w_k, w_v = pair
+            w_dict.setitem(w_k, w_v)
+    else:
+        if space.is_true(w_src):
+            from pypy.objspace.std.dicttype import dict_update__ANY_ANY
+            dict_update__ANY_ANY(space, w_dict, w_src)
+    if space.is_true(w_kwds):
+        from pypy.objspace.std.dicttype import dict_update__ANY_ANY
+        dict_update__ANY_ANY(space, w_dict, w_kwds)
+
+def getitem__DictStr_ANY(space, w_dict, w_lookup):
+    try:
+        return w_dict.getitem(w_lookup)
+    except KeyError:
+        raise OperationError(space.w_KeyError, w_lookup)
+
+def setitem__DictStr_ANY_ANY(space, w_dict, w_newkey, w_newvalue):
+    w_dict.setitem(w_newkey, w_newvalue)
+
+def delitem__DictStr_ANY(space, w_dict, w_lookup):
+    try:
+        if w_dict.content is None:
+            if space.is_w(space.type(w_lookup), space.w_str):
+                del w_dict.content_str[space.str_w(w_lookup)]
+                return
+            else:
+                w_dict.str2object()
+        del w_dict.content[w_lookup]
+    except KeyError:
+        raise OperationError(space.w_KeyError, w_lookup)
+    
+def len__DictStr(space, w_dict):
+    return space.wrap(w_dict.len())
+
+def contains__DictStr_ANY(space, w_dict, w_lookup):
+    if w_dict.content is None:
+        if not space.is_w(space.type(w_lookup), space.w_str):
+            w_dict.str2object()
+        else:
+            return space.newbool(space.str_w(w_lookup) in w_dict.content_str)
+    return space.newbool(w_lookup in w_dict.content)
+
+dict_has_key__DictStr_ANY = contains__DictStr_ANY
+
+def iter__DictStr(space, w_dict):
+    return dict_iterkeys__DictStr(space, w_dict)
+
+def equal_str_str(space, w_left, w_right):
+    """ This is not a multimethod. """
+    if len(w_left.content_str) != len(w_right.content_str):
+        return space.w_False
+    
+    for key, w_val in w_left.content_str.iteritems():
+        try:
+            w_rightval = w_right.content_str[key]
+        except KeyError:
+            return space.w_False
+        if not space.eq_w(w_val, w_rightval):
+            return space.w_False
+    return space.w_True
+
+def equal_object_object(space, w_left, w_right):
+    """ This is not a multimethod. """
+    
+    if len(w_left.content) != len(w_right.content):
+        return space.w_False
+
+    for w_key, w_val in w_left.content.iteritems():
+        try:
+            w_rightval = w_right.content[w_key]
+        except KeyError:
+            return space.w_False
+        if not space.eq_w(w_val, w_rightval):
+            return space.w_False
+    return space.w_True
+    
+def eq__DictStr_DictStr(space, w_left, w_right):
+    if space.is_w(w_left, w_right):
+        return space.w_True
+
+    if w_left.content_str is not None and w_right.content_str is not None:
+        return equal_str_str(space, w_left, w_right)
+
+    if w_left.content is None:
+        w_left.str2object()
+    if w_right.content is None:
+        w_right.str2object()
+
+    return equal_object_object(space, w_left, w_right)
+
+def characterize(space, acontent, bcontent):
+    """ (similar to CPython) 
+    returns the smallest key in acontent for which b's value is different or absent and this value """
+    w_smallest_diff_a_key = None
+    w_its_value = None
+    for w_key, w_val in acontent.iteritems():
+        if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)):
+            try:
+                w_bvalue = bcontent[w_key]
+            except KeyError:
+                w_its_value = w_val
+                w_smallest_diff_a_key = w_key
+            else:
+                if not space.eq_w(w_val, w_bvalue):
+                    w_its_value = w_val
+                    w_smallest_diff_a_key = w_key
+    return w_smallest_diff_a_key, w_its_value
+
+def lt__DictStr_DictStr(space, w_left, w_right):
+    # XXX would it make sense to make str special cases?
+    if w_left.content is None:
+        w_left.str2object()
+    if w_right.content is None:
+        w_right.str2object()
+
+    # Different sizes, no problem
+    leftcontent = w_left.content
+    rightcontent = w_right.content
+    if len(leftcontent) < len(rightcontent):
+        return space.w_True
+    if len(leftcontent) > len(rightcontent):
+        return space.w_False
+
+    # Same size
+    w_leftdiff, w_leftval = characterize(space, leftcontent, rightcontent)
+    if w_leftdiff is None:
+        return space.w_False
+    w_rightdiff, w_rightval = characterize(space, rightcontent, leftcontent)
+    if w_rightdiff is None:
+        # w_leftdiff is not None, w_rightdiff is None
+        return space.w_True 
+    w_res = space.lt(w_leftdiff, w_rightdiff)
+    if (not space.is_true(w_res) and
+        space.eq_w(w_leftdiff, w_rightdiff) and 
+        w_rightval is not None):
+        w_res = space.lt(w_leftval, w_rightval)
+    return w_res
+
+def dict_copy__DictStr(space, w_self):
+    return W_DictStrObject(space, w_self)
+
+def dict_items__DictStr(space, w_self):
+    if w_self.content is not None:
+        l = [space.newtuple([w_key, w_value]) for w_key, w_value in w_self.content.iteritems()]
+    else:
+        l = [space.newtuple([space.wrap(key), w_value]) for key, w_value in w_self.content_str.iteritems()]
+    return space.newlist(l)
+
+def dict_keys__DictStr(space, w_self):
+    if w_self.content is None:
+        return space.newlist([space.wrap(x) for x in w_self.content_str.keys()])
+    else:
+        return space.newlist(w_self.content.keys())
+
+def dict_values__DictStr(space, w_self):
+    if w_self.content is None:
+        l = w_self.content_str.values()
+    else:
+        l = w_self.content.values()
+    return space.newlist(l)
+
+def dict_iteritems__DictStr(space, w_self):
+    if w_self.content is None:
+        return W_DictIter_Items_str(space, w_self)
+    return W_DictIter_Items_obj(space, w_self)
+
+def dict_iterkeys__DictStr(space, w_self):
+    if w_self.content is None:
+        return W_DictIter_Keys_str(space, w_self)
+    return W_DictIter_Keys_obj(space, w_self)
+
+def dict_itervalues__DictStr(space, w_self):
+    if w_self.content is None:
+        return W_DictIter_Values_str(space, w_self)
+    return W_DictIter_Values_obj(space, w_self)
+
+def dict_clear__DictStr(space, w_self):
+    if w_self.content is None:
+        w_self.content_str.clear()
+    else:
+        w_self.content.clear()
+
+def dict_get__DictStr_ANY_ANY(space, w_dict, w_lookup, w_default):
+    if w_dict.content is None:
+        return w_dict.content_str.get(space.str_w(w_lookup), w_default)
+    return w_dict.content.get(w_lookup, w_default)
+
+app = gateway.applevel('''
+    def dictrepr(currently_in_repr, d):
+        # Now we only handle one implementation of dicts, this one.
+        # The fix is to move this to dicttype.py, and do a
+        # multimethod lookup mapping str to StdObjSpace.str
+        # This cannot happen until multimethods are fixed. See dicttype.py
+            dict_id = id(d)
+            if dict_id in currently_in_repr:
+                return '{...}'
+            currently_in_repr[dict_id] = 1
+            try:
+                items = []
+                # XXX for now, we cannot use iteritems() at app-level because
+                #     we want a reasonable result instead of a RuntimeError
+                #     even if the dict is mutated by the repr() in the loop.
+                for k, v in d.items():
+                    items.append(repr(k) + ": " + repr(v))
+                return "{" +  ', '.join(items) + "}"
+            finally:
+                try:
+                    del currently_in_repr[dict_id]
+                except:
+                    pass
+''', filename=__file__)
+
+dictrepr = app.interphook("dictrepr")
+
+def repr__DictStr(space, w_dict):
+    if w_dict.len() == 0:
+        return space.wrap('{}')
+
+    w_currently_in_repr = space.getexecutioncontext()._py_repr
+    return dictrepr(space, w_currently_in_repr, w_dict)
+
+
+# ____________________________________________________________
+# Iteration
+
+class W_DictStrIterObject(W_Object):
+    from pypy.objspace.std.dicttype import dictiter_typedef as typedef
+
+    def __init__(w_self, space, w_dictobject):
+        w_self.space = space
+        w_self.w_dictobject = w_dictobject
+        w_self.content = w_dictobject.content
+        w_self.content_str = w_dictobject.content_str
+        w_self.len = w_dictobject.len()
+        w_self.pos = 0
+        w_self.setup_iterator()
+
+    def return_entry(w_self, w_key, w_value):
+        raise NotImplementedError
+
+registerimplementation(W_DictStrIterObject)
+
+class W_DictStrIter_Keys(W_DictStrIterObject):
+    pass
+
+class W_DictIter_Keys_obj(W_DictStrIter_Keys):
+    def setup_iterator(w_self):
+        w_self.iterator = w_self.content.iterkeys()
+
+    def next_entry(w_self):
+        # note that these 'for' loops only run once, at most
+
+        for w_key in w_self.iterator:
+            return w_key
+        else:
+            return None
+
+class W_DictIter_Keys_str(W_DictStrIter_Keys):
+    def setup_iterator(w_self):
+        w_self.iterator = w_self.content_str.iterkeys()
+
+    def next_entry(w_self):
+        # note that these 'for' loops only run once, at most
+
+        for key in w_self.iterator:
+            return w_self.space.wrap(key)
+        else:
+            return None
+
+class W_DictStrIter_Values(W_DictStrIterObject):
+    pass
+
+class W_DictIter_Values_obj(W_DictStrIter_Values):
+    def next_entry(w_self):
+        # note that these 'for' loops only run once, at most
+
+        for w_value in w_self.iterator:
+            return w_value
+        else:
+            return None
+
+    def setup_iterator(w_self):
+        w_self.iterator = w_self.content.itervalues()
+
+class W_DictIter_Values_str(W_DictStrIter_Values):
+    def next_entry(w_self):
+        # note that these 'for' loops only run once, at most
+
+        for w_value in w_self.iterator:
+            return w_value
+        else:
+            return None
+
+    def setup_iterator(w_self):
+        w_self.iterator = w_self.content_str.itervalues()
+
+class W_DictStrIter_Items(W_DictStrIterObject):
+    pass
+
+class W_DictIter_Items_obj(W_DictStrIter_Items):
+    def setup_iterator(w_self):
+        w_self.iterator = w_self.content.iteritems()
+    
+    def next_entry(w_self):
+        # note that these 'for' loops only run once, at most
+
+        for w_key, w_value in w_self.iterator:
+            return w_self.space.newtuple([w_key, w_value])
+        else:
+            return None
+
+class W_DictIter_Items_str(W_DictStrIter_Items):
+    def setup_iterator(w_self):
+        w_self.iterator_str = w_self.content_str.iteritems()
+
+    def next_entry(w_self):
+        # note that these 'for' loops only run once, at most
+
+        for key, w_value in w_self.iterator_str:
+            return w_self.space.newtuple([w_self.space.wrap(key), w_value])
+        else:
+            return None
+
+def iter__DictStrIterObject(space, w_dictiter):
+    return w_dictiter
+
+def next__DictStrIterObject(space, w_dictiter):
+    # XXX hum, this is broken currently
+    if w_dictiter.content_str is not None and w_dictiter.w_dictobject.content_str is None:
+        raise OperationError(space.w_RuntimeError,
+                space.wrap("you stupid dictionary user - you have just done an operation internally mutating the dictionary"))
+
+    if w_dictiter.content is not None:
+        if w_dictiter.len != len(w_dictiter.content):
+            w_dictiter.len = -1   # Make this error state sticky
+            raise OperationError(space.w_RuntimeError,
+                     space.wrap("dictionary changed size during iteration"))
+        # look for the next entry
+        w_result = w_dictiter.next_entry()
+        if w_result is not None:
+            w_dictiter.pos += 1
+            return w_result
+        # no more entries
+        w_dictiter.content = None
+    else:
+        if w_dictiter.content_str is not None:
+            if w_dictiter.len != len(w_dictiter.content_str):
+                w_dictiter.len = -1   # Make this error state sticky
+                raise OperationError(space.w_RuntimeError,
+                         space.wrap("dictionary changed size during iteration"))
+            # look for the next entry
+            w_result = w_dictiter.next_entry()
+            if w_result is not None:
+                w_dictiter.pos += 1
+                return w_result
+            # no more entries
+            w_dictiter.content_str = None
+    raise OperationError(space.w_StopIteration, space.w_None)
+
+def len__DictStrIterObject(space, w_dictiter):
+    # doesn't check for mutation?
+    if (w_dictiter.content is None and w_dictiter.content_str is None) or w_dictiter.len == -1:
+        return space.wrap(0)
+        
+    return space.wrap(w_dictiter.len - w_dictiter.pos)
+
+# ____________________________________________________________
+
+from pypy.objspace.std import dicttype
+register_all(vars(), dicttype)

Modified: pypy/branch/objspace-config-cleanup/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/branch/objspace-config-cleanup/pypy/objspace/std/dicttype.py	(original)
+++ pypy/branch/objspace-config-cleanup/pypy/objspace/std/dicttype.py	Sat Jul  8 15:51:36 2006
@@ -124,9 +124,8 @@
 # ____________________________________________________________
 
 def descr__new__(space, w_dicttype, __args__):
-    from pypy.objspace.std.dictobject import W_DictObject
-    w_obj = space.allocate_instance(W_DictObject, w_dicttype)
-    W_DictObject.__init__(w_obj, space)
+    w_obj = space.allocate_instance(space.DictObjectCls, w_dicttype)
+    space.DictObjectCls.__init__(w_obj, space)
     return w_obj
 
 # ____________________________________________________________
@@ -183,6 +182,8 @@
     # we cannot call __init__ since we don't have the original dict
     w_clone.space = space
     w_clone.content = w_self.content
+    if space.config.objspace.std.withstrdict:
+        w_clone.content_str = w_self.content_str
     w_clone.len = w_self.len
     w_clone.pos = 0
     w_clone.setup_iterator()

Modified: pypy/branch/objspace-config-cleanup/pypy/objspace/std/marshal_impl.py
==============================================================================
--- pypy/branch/objspace-config-cleanup/pypy/objspace/std/marshal_impl.py	(original)
+++ pypy/branch/objspace-config-cleanup/pypy/objspace/std/marshal_impl.py	Sat Jul  8 15:51:36 2006
@@ -25,6 +25,7 @@
 from pypy.objspace.std.tupleobject   import W_TupleObject
 from pypy.objspace.std.listobject    import W_ListObject
 from pypy.objspace.std.dictobject    import W_DictObject
+from pypy.objspace.std.dictstrobject    import W_DictStrObject
 from pypy.objspace.std.stringobject  import W_StringObject
 from pypy.objspace.std.typeobject    import W_TypeObject
 from pypy.objspace.std.longobject    import W_LongObject
@@ -347,18 +348,29 @@
         m.put_w_obj(w_value)
     m.atom(TYPE_NULL)
 
+def marshal_w__DictStr(space, w_dict, m):
+    m.start(TYPE_DICT)
+    if w_dict.content is not None:
+        for w_key, w_value in w_dict.content.iteritems():
+            m.put_w_obj(w_key)
+            m.put_w_obj(w_value)
+    else:
+        for key, w_value in w_dict.content_str.iteritems():
+            m.put_w_obj(space.wrap(key))
+            m.put_w_obj(w_value)
+    m.atom(TYPE_NULL)
+
 def unmarshal_Dict(space, u, tc):
     # since primitive lists are not optimized and we don't know
     # the dict size in advance, use the dict's setitem instead
     # of building a list of tuples.
-    w_dic = W_DictObject(space)
-    setter = dictobject.setitem__Dict_ANY_ANY
+    w_dic = space.newdict([])
     while 1:
         w_key = u.get_w_obj(True)
         if w_key is None:
             break
         w_value = u.get_w_obj(False)
-        setter(space, w_dic, w_key, w_value)
+        space.setitem(w_dic, w_key, w_value)
     return w_dic
 register(TYPE_DICT, unmarshal_Dict)
 

Modified: pypy/branch/objspace-config-cleanup/pypy/objspace/std/model.py
==============================================================================
--- pypy/branch/objspace-config-cleanup/pypy/objspace/std/model.py	(original)
+++ pypy/branch/objspace-config-cleanup/pypy/objspace/std/model.py	Sat Jul  8 15:51:36 2006
@@ -9,9 +9,11 @@
 import pypy.interpreter.special
 
 option_to_typename = {
-    "withsmallint"   : "smallintobject.W_SmallIntObject",
-    "withstrslice"   : "strsliceobject.W_StringSliceObject",
-    "withstrjoin"    : "strjoinobject.W_StringJoinObject",
+    "withsmallint"   : ["smallintobject.W_SmallIntObject"],
+    "withstrslice"   : ["strsliceobject.W_StringSliceObject"],
+    "withstrjoin"    : ["strjoinobject.W_StringJoinObject"],
+    "withstrdict"    : ["dictstrobject.W_DictStrObject",
+                        "dictstrobject.W_DictStrIterObject"],
 }
 
 class StdTypeModel:
@@ -55,6 +57,7 @@
         from pypy.objspace.std import tupleobject
         from pypy.objspace.std import listobject
         from pypy.objspace.std import dictobject
+        from pypy.objspace.std import dictstrobject
         from pypy.objspace.std import stringobject
         from pypy.objspace.std import strsliceobject
         from pypy.objspace.std import strjoinobject
@@ -96,14 +99,24 @@
         self.typeorder[setobject.W_SetObject] = []
         self.typeorder[setobject.W_FrozensetObject] = []
         self.typeorder[setobject.W_SetIterObject] = []
-        imported_but_not_registered = {}
+
+        imported_but_not_registered = {
+            dictobject.W_DictObject: True,
+            dictobject.W_DictIterObject: True,
+        }
         for option, value in config.objspace.std:
             if option.startswith("with") and option in option_to_typename:
-                implcls = eval(option_to_typename[option])
-                if value:
-                    self.typeorder[implcls] = []
-                else:
-                    imported_but_not_registered[implcls] = True
+                for classname in option_to_typename[option]:
+                    implcls = eval(classname)
+                    if value:
+                        self.typeorder[implcls] = []
+                    else:
+                        imported_but_not_registered[implcls] = True
+
+        if config.objspace.std.withstrdict:
+            del self.typeorder[dictobject.W_DictObject]
+            del self.typeorder[dictobject.W_DictIterObject]
+
         #check if we missed implementations
         from pypy.objspace.std.objspace import _registered_implementations
         for implcls in _registered_implementations:

Modified: pypy/branch/objspace-config-cleanup/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/objspace-config-cleanup/pypy/objspace/std/objspace.py	(original)
+++ pypy/branch/objspace-config-cleanup/pypy/objspace/std/objspace.py	Sat Jul  8 15:51:36 2006
@@ -54,6 +54,14 @@
         # Import all the object types and implementations
         self.model = StdTypeModel(self.config)
 
+        # XXX store the dict class on the space to access it in various places
+        if self.config.objspace.std.withstrdict:
+            from pypy.objspace.std import dictstrobject
+            self.DictObjectCls = dictstrobject.W_DictStrObject
+        else:
+            from pypy.objspace.std import dictobject
+            self.DictObjectCls = dictobject.W_DictObject
+
         # install all the MultiMethods into the space instance
         for name, mm in self.MM.__dict__.items():
             if isinstance(mm, StdObjSpaceMultiMethod) and not hasattr(self, name):
@@ -372,7 +380,7 @@
         return W_ListObject(list_w)
 
     def newdict(self, list_pairs_w):
-        w_result = W_DictObject(self)
+        w_result = self.DictObjectCls(self)
         w_result.initialize_content(list_pairs_w)
         return w_result
 
@@ -444,22 +452,30 @@
         return w_one is w_two
 
     def is_true(self, w_obj):
-        # XXX don't look!
-        if type(w_obj) is W_DictObject:
-            return len(w_obj.content) != 0
+        if self.config.objspace.std.withstrdict:
+            from pypy.objspace.std.dictstrobject import W_DictStrObject
+            if type(w_obj) is W_DictStrObject:
+                return w_obj.len() != 0
         else:
-            return DescrOperation.is_true(self, w_obj)
+            # XXX don't look!
+            if type(w_obj) is W_DictObject:
+                return len(w_obj.content) != 0
+            else:
+                return DescrOperation.is_true(self, w_obj)
 
     def finditem(self, w_obj, w_key):
         # performance shortcut to avoid creating the OperationError(KeyError)
-        if type(w_obj) is W_DictObject:
-            return w_obj.content.get(w_key, None)
+        if type(w_obj) is self.DictObjectCls:
+            if not self.config.objspace.std.withstrdict:
+                return w_obj.content.get(w_key, None)
         else:
-            return ObjSpace.finditem(self, w_obj, w_key)
+            #XXX fix this here!
+            pass
+        return ObjSpace.finditem(self, w_obj, w_key)
 
     def set_str_keyed_item(self, w_obj, w_key, w_value):
         # performance shortcut to avoid creating the OperationError(KeyError)
-        if type(w_obj) is W_DictObject:
+        if type(w_obj) is self.DictObjectCls:
             w_obj.content[w_key] = w_value
         else:
             self.setitem(w_obj, w_key, w_value)

Modified: pypy/branch/objspace-config-cleanup/pypy/objspace/std/test/test_dictobject.py
==============================================================================
--- pypy/branch/objspace-config-cleanup/pypy/objspace/std/test/test_dictobject.py	(original)
+++ pypy/branch/objspace-config-cleanup/pypy/objspace/std/test/test_dictobject.py	Sat Jul  8 15:51:36 2006
@@ -1,19 +1,21 @@
 import autopath
 from pypy.objspace.std.dictobject import W_DictObject
-
-
+from pypy.conftest import gettestobjspace
 
 class TestW_DictObject:
 
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withstrdict": False})
+
     def test_empty(self):
         space = self.space
-        d = W_DictObject(space)
+        d = self.space.DictObjectCls(space)
         assert not self.space.is_true(d)
 
     def test_nonempty(self):
         space = self.space
         wNone = space.w_None
-        d = W_DictObject(space)
+        d = self.space.DictObjectCls(space)
         d.initialize_content([(wNone, wNone)])
         assert space.is_true(d)
         i = space.getitem(d, wNone)
@@ -24,7 +26,7 @@
         space = self.space
         wk1 = space.wrap('key')
         wone = space.wrap(1)
-        d = W_DictObject(space)
+        d = self.space.DictObjectCls(space)
         d.initialize_content([(space.wrap('zero'),space.wrap(0))])
         space.setitem(d,wk1,wone)
         wback = space.getitem(d,wk1)
@@ -33,7 +35,7 @@
     def test_delitem(self):
         space = self.space
         wk1 = space.wrap('key')
-        d = W_DictObject(space)
+        d = self.space.DictObjectCls(space)
         d.initialize_content( [(space.wrap('zero'),space.wrap(0)),
                                (space.wrap('one'),space.wrap(1)),
                                (space.wrap('two'),space.wrap(2))])
@@ -44,7 +46,7 @@
                             space.getitem,d,space.wrap('one'))
 
     def test_wrap_dict(self):
-        assert isinstance(self.space.wrap({}), W_DictObject)
+        assert isinstance(self.space.wrap({}), self.space.DictObjectCls)
 
 
     def test_dict_compare(self):
@@ -354,6 +356,7 @@
     eq_w = eq
     def newlist(self, l):
         return []
+    DictObjectCls = W_DictObject
 
 from pypy.objspace.std.dictobject import getitem__Dict_ANY, setitem__Dict_ANY_ANY
 
@@ -364,7 +367,7 @@
 
     def test_stressdict(self):
         from random import randint
-        d = W_DictObject(self.space)
+        d = self.space.DictObjectCls(self.space)
         N = 10000
         pydict = {}
         for i in range(N):

Added: pypy/branch/objspace-config-cleanup/pypy/objspace/std/test/test_dictstrobject.py
==============================================================================
--- (empty file)
+++ pypy/branch/objspace-config-cleanup/pypy/objspace/std/test/test_dictstrobject.py	Sat Jul  8 15:51:36 2006
@@ -0,0 +1,19 @@
+import autopath
+from pypy.objspace.std.dictstrobject import W_DictStrObject
+from pypy.conftest import gettestobjspace
+from pypy.objspace.std.test import test_dictobject
+
+class TestW_DictObject(test_dictobject.TestW_DictObject):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withstrdict": True})
+
+class AppTest_DictObject(test_dictobject.AppTest_DictObject):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withstrdict": True})
+
+class TestDictImplementation(test_dictobject.TestDictImplementation):
+    def setup_method(self,method):
+        self.space = test_dictobject.FakeSpace()
+        self.space.DictObjectCls = W_DictStrObject
+
+    



More information about the Pypy-commit mailing list