Author: Philip Jenvey <pjen...@underboss.org>
Branch: py3k
Changeset: r64289:bd92c9da8b05
Date: 2013-05-17 11:28 -0700
http://bitbucket.org/pypy/pypy/changeset/bd92c9da8b05/

Log:    merge default

diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst
--- a/pypy/doc/how-to-contribute.rst
+++ b/pypy/doc/how-to-contribute.rst
@@ -28,7 +28,8 @@
 Layers
 ------
 
-PyPy has layers. Those layers help us keep the respective parts separated 
enough
+PyPy has layers. Just like Ogres or onions.
+Those layers help us keep the respective parts separated enough
 to be worked on independently and make the complexity manageable. This is,
 again, just a sanity requirement for such a complex project. For example 
writing
 a new optimization for the JIT usually does **not** involve touching a Python
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -19,3 +19,6 @@
 
 .. branch: numpy-subarrays
 Implement subarrays for numpy
+
+.. branch: remove-dict-smm
+Remove multi-methods on dict
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -245,6 +245,11 @@
     def __spacebind__(self, space):
         return self
 
+    def unwrap(self, space):
+        """NOT_RPYTHON"""
+        # _____ this code is here to support testing only _____
+        return self
+
 
 class W_InterpIterable(W_Root):
     def __init__(self, space, w_iterable):
diff --git a/pypy/interpreter/test/test_app_main.py 
b/pypy/interpreter/test/test_app_main.py
--- a/pypy/interpreter/test/test_app_main.py
+++ b/pypy/interpreter/test/test_app_main.py
@@ -1039,7 +1039,7 @@
             import app_main
             app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found
             assert sys.executable == ''
-            assert sys.path == old_sys_path + [self.goal_dir]
+            assert sys.path == old_sys_path
 
             app_main.setup_bootstrap_path(self.fake_exe)
             assert sys.executable == self.fake_exe
diff --git a/pypy/objspace/std/dictmultiobject.py 
b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -1,19 +1,19 @@
-import py, sys
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.setobject import set_typedef as settypedef
-from pypy.objspace.std.setobject import frozenset_typedef as frozensettypedef
+from pypy.interpreter import gateway
+from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.mixedmodule import MixedModule
 from pypy.interpreter.signature import Signature
+from pypy.objspace.std.stdtypedef import StdTypeDef
 
+from rpython.rlib import rerased, jit
+from rpython.rlib.debug import mark_dict_non_null
 from rpython.rlib.objectmodel import r_dict, specialize, newlist_hint
-from rpython.rlib.debug import mark_dict_non_null
 from rpython.tool.sourcetools import func_with_new_name
 
-from rpython.rlib import rerased, jit
 
 UNROLL_CUTOFF = 5
 
+
 def _is_str(space, w_key):
     return space.is_w(space.type(w_key), space.w_str)
 
@@ -40,9 +40,20 @@
                                     w_dct.length() <= UNROLL_CUTOFF)
 
 
-class W_DictMultiObject(W_Object):
-    from pypy.objspace.std.dicttype import dict_typedef as typedef
+def negate(f):
+    def _negator(self, space, w_other):
+        # no need to use space.is_ / space.not_
+        tmp = f(self, space, w_other)
+        if tmp is space.w_NotImplemented:
+            return space.w_NotImplemented
+        elif tmp is space.w_False:
+            return space.w_True
+        else:
+            return space.w_False
+    _negator.func_name = 'negate-%s' % f.func_name
+    return _negator
 
+class W_DictMultiObject(W_Root):
     @staticmethod
     def allocate_and_init_instance(space, w_type=None, module=False,
                                    instance=False, strdict=False, 
kwargs=False):
@@ -109,6 +120,230 @@
     def setitem_str(self, key, w_value):
         self.strategy.setitem_str(self, key, w_value)
 
+    @staticmethod
+    def descr_new(space, w_dicttype, __args__):
+        w_obj = W_DictMultiObject.allocate_and_init_instance(space, w_dicttype)
+        return w_obj
+
+    @staticmethod
+    def descr_fromkeys(space, w_type, w_keys, w_fill=None):
+        if w_fill is None:
+            w_fill = space.w_None
+        if space.is_w(w_type, space.w_dict):
+            w_dict = W_DictMultiObject.allocate_and_init_instance(space, 
w_type)
+
+            strlist = space.listview_str(w_keys)
+            if strlist is not None:
+                for key in strlist:
+                    w_dict.setitem_str(key, w_fill)
+            else:
+                for w_key in space.listview(w_keys):
+                    w_dict.setitem(w_key, w_fill)
+        else:
+            w_dict = space.call_function(w_type)
+            for w_key in space.listview(w_keys):
+                space.setitem(w_dict, w_key, w_fill)
+        return w_dict
+
+    def descr_init(self, space, __args__):
+        init_or_update(space, self, __args__, 'dict')
+
+    def descr_repr(self, space):
+        ec = space.getexecutioncontext()
+        w_currently_in_repr = ec._py_repr
+        if w_currently_in_repr is None:
+            w_currently_in_repr = ec._py_repr = space.newdict()
+        return dictrepr(space, w_currently_in_repr, self)
+
+    def descr_eq(self, space, w_other):
+        if space.is_w(self, w_other):
+            return space.w_True
+        if not isinstance(w_other, W_DictMultiObject):
+            return space.w_NotImplemented
+
+        if self.length() != w_other.length():
+            return space.w_False
+        iteratorimplementation = self.iteritems()
+        while 1:
+            w_key, w_val = iteratorimplementation.next_item()
+            if w_key is None:
+                break
+            w_rightval = w_other.getitem(w_key)
+            if w_rightval is None:
+                return space.w_False
+            if not space.eq_w(w_val, w_rightval):
+                return space.w_False
+        return space.w_True
+
+    def descr_lt(self, space, w_other):
+        if not isinstance(w_other, W_DictMultiObject):
+            return space.w_NotImplemented
+        return self._compare_lt(space, w_other)
+
+    def descr_gt(self, space, w_other):
+        if not isinstance(w_other, W_DictMultiObject):
+            return space.w_NotImplemented
+        return w_other._compare_lt(space, self)
+
+    def _compare_lt(self, space, w_other):
+        # Different sizes, no problem
+        if self.length() < w_other.length():
+            return space.w_True
+        if self.length() > w_other.length():
+            return space.w_False
+
+        # Same size
+        w_leftdiff, w_leftval = characterize(space, self, w_other)
+        if w_leftdiff is None:
+            return space.w_False
+        w_rightdiff, w_rightval = characterize(space, w_other, self)
+        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
+
+    descr_ne = negate(descr_eq)
+    descr_le = negate(descr_gt)
+    descr_ge = negate(descr_lt)
+
+    def descr_len(self, space):
+        return space.wrap(self.length())
+
+    def descr_iter(self, space):
+        return W_DictMultiIterKeysObject(space, self.iterkeys())
+
+    def descr_contains(self, space, w_key):
+        return space.newbool(self.getitem(w_key) is not None)
+
+    def descr_getitem(self, space, w_key):
+        w_value = self.getitem(w_key)
+        if w_value is not None:
+            return w_value
+
+        w_missing_item = self.missing_method(space, w_key)
+        if w_missing_item is not None:
+            return w_missing_item
+
+        space.raise_key_error(w_key)
+
+    def descr_setitem(self, space, w_newkey, w_newvalue):
+        self.setitem(w_newkey, w_newvalue)
+
+    def descr_delitem(self, space, w_key):
+        try:
+            self.delitem(w_key)
+        except KeyError:
+            space.raise_key_error(w_key)
+
+    def descr_reversed(self, space):
+        raise OperationError(space.w_TypeError, space.wrap('argument to 
reversed() must be a sequence'))
+
+    def descr_copy(self, space):
+        """D.copy() -> a shallow copy of D"""
+        w_new = W_DictMultiObject.allocate_and_init_instance(space)
+        update1_dict_dict(space, w_new, self)
+        return w_new
+
+    def descr_items(self, space):
+        """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
+        return space.newlist(self.items())
+
+    def descr_keys(self, space):
+        """D.keys() -> list of D's keys"""
+        return self.w_keys()
+
+    def descr_values(self, space):
+        """D.values() -> list of D's values"""
+        return space.newlist(self.values())
+
+    def descr_iteritems(self, space):
+        """D.iteritems() -> an iterator over the (key, value) items of D"""
+        return W_DictMultiIterItemsObject(space, self.iteritems())
+
+    def descr_iterkeys(self, space):
+        """D.iterkeys() -> an iterator over the keys of D"""
+        return W_DictMultiIterKeysObject(space, self.iterkeys())
+
+    def descr_itervalues(self, space):
+        """D.itervalues() -> an iterator over the values of D"""
+        return W_DictMultiIterValuesObject(space, self.itervalues())
+
+    def descr_viewitems(self, space):
+        """D.viewitems() -> a set-like object providing a view on D's items"""
+        return W_DictViewItemsObject(space, self)
+
+    def descr_viewkeys(self, space):
+        """D.viewkeys() -> a set-like object providing a view on D's keys"""
+        return W_DictViewKeysObject(space, self)
+
+    def descr_viewvalues(self, space):
+        """D.viewvalues() -> an object providing a view on D's values"""
+        return W_DictViewValuesObject(space, self)
+
+    def descr_has_key(self, space, w_key):
+        """D.has_key(k) -> True if D has a key k, else False"""
+        return space.newbool(self.getitem(w_key) is not None)
+
+    def descr_clear(self, space):
+        """D.clear() -> None.  Remove all items from D."""
+        self.clear()
+
+    @gateway.unwrap_spec(w_default=gateway.WrappedDefault(None))
+    def descr_get(self, space, w_key, w_default):
+        """D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None."""
+        w_value = self.getitem(w_key)
+        if w_value is not None:
+            return w_value
+        else:
+            return w_default
+
+    @gateway.unwrap_spec(defaults_w='args_w')
+    def descr_pop(self, space, w_key, defaults_w):
+        """D.pop(k[,d]) -> v, remove specified key and return the
+        corresponding value\nIf key is not found, d is returned if given,
+        otherwise KeyError is raised
+        """
+        len_defaults = len(defaults_w)
+        if len_defaults > 1:
+            raise operationerrfmt(space.w_TypeError,
+                                  "pop expected at most 2 arguments, got %d",
+                                  1 + len_defaults)
+        w_item = self.getitem(w_key)
+        if w_item is None:
+            if len_defaults > 0:
+                return defaults_w[0]
+            else:
+                space.raise_key_error(w_key)
+        else:
+            self.delitem(w_key)
+            return w_item
+
+    def descr_popitem(self, space):
+        """D.popitem() -> (k, v), remove and return some (key, value) pair as
+        a\n2-tuple; but raise KeyError if D is empty"""
+        try:
+            w_key, w_value = self.popitem()
+        except KeyError:
+            raise OperationError(space.w_KeyError,
+                                 space.wrap("popitem(): dictionary is empty"))
+        return space.newtuple([w_key, w_value])
+
+    @gateway.unwrap_spec(w_default=gateway.WrappedDefault(None))
+    def descr_setdefault(self, space, w_key, w_default):
+        """D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"""
+        return self.setdefault(w_key, w_default)
+
+    def descr_update(self, space, __args__):
+        """D.update(E, **F) -> None.  Update D from E and F: for k in E: D[k]
+        = E[k]\n(if E has keys else: for (k, v) in E: D[k] = v) then: for k in
+        F: D[k] = F[k]"""
+        init_or_update(space, self, __args__, 'dict.update')
+
 
 def _add_indirections():
     dict_methods = "getitem getitem_str setitem setdefault \
@@ -129,8 +364,87 @@
 
 _add_indirections()
 
+
+app = gateway.applevel('''
+    def dictrepr(currently_in_repr, d):
+        if len(d) == 0:
+            return "{}"
+        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 dict.items(d):
+                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")
+
+
+W_DictMultiObject.typedef = StdTypeDef("dict",
+    __doc__ = '''dict() -> new empty dictionary.
+dict(mapping) -> new dictionary initialized from a mapping object\'s
+    (key, value) pairs.
+dict(seq) -> new dictionary initialized as if via:
+    d = {}
+    for k, v in seq:
+        d[k] = v
+dict(**kwargs) -> new dictionary initialized with the name=value pairs
+    in the keyword argument list.  For example:  dict(one=1, two=2)''',
+    __new__ = gateway.interp2app(W_DictMultiObject.descr_new),
+    fromkeys = gateway.interp2app(W_DictMultiObject.descr_fromkeys,
+                                  as_classmethod=True),
+    __hash__ = None,
+    __repr__ = gateway.interp2app(W_DictMultiObject.descr_repr),
+    __init__ = gateway.interp2app(W_DictMultiObject.descr_init),
+
+    __eq__ = gateway.interp2app(W_DictMultiObject.descr_eq),
+    __ne__ = gateway.interp2app(W_DictMultiObject.descr_ne),
+    __lt__ = gateway.interp2app(W_DictMultiObject.descr_lt),
+    __le__ = gateway.interp2app(W_DictMultiObject.descr_le),
+    __gt__ = gateway.interp2app(W_DictMultiObject.descr_gt),
+    __ge__ = gateway.interp2app(W_DictMultiObject.descr_ge),
+
+    __len__ = gateway.interp2app(W_DictMultiObject.descr_len),
+    __iter__ = gateway.interp2app(W_DictMultiObject.descr_iter),
+    __contains__ = gateway.interp2app(W_DictMultiObject.descr_contains),
+
+    __getitem__ = gateway.interp2app(W_DictMultiObject.descr_getitem),
+    __setitem__ = gateway.interp2app(W_DictMultiObject.descr_setitem),
+    __delitem__ = gateway.interp2app(W_DictMultiObject.descr_delitem),
+
+    __reversed__ = gateway.interp2app(W_DictMultiObject.descr_reversed),
+    copy = gateway.interp2app(W_DictMultiObject.descr_copy),
+    items = gateway.interp2app(W_DictMultiObject.descr_items),
+    keys = gateway.interp2app(W_DictMultiObject.descr_keys),
+    values = gateway.interp2app(W_DictMultiObject.descr_values),
+    iteritems = gateway.interp2app(W_DictMultiObject.descr_iteritems),
+    iterkeys = gateway.interp2app(W_DictMultiObject.descr_iterkeys),
+    itervalues = gateway.interp2app(W_DictMultiObject.descr_itervalues),
+    viewkeys = gateway.interp2app(W_DictMultiObject.descr_viewkeys),
+    viewitems = gateway.interp2app(W_DictMultiObject.descr_viewitems),
+    viewvalues = gateway.interp2app(W_DictMultiObject.descr_viewvalues),
+    has_key = gateway.interp2app(W_DictMultiObject.descr_has_key),
+    clear = gateway.interp2app(W_DictMultiObject.descr_clear),
+    get = gateway.interp2app(W_DictMultiObject.descr_get),
+    pop = gateway.interp2app(W_DictMultiObject.descr_pop),
+    popitem = gateway.interp2app(W_DictMultiObject.descr_popitem),
+    setdefault = gateway.interp2app(W_DictMultiObject.descr_setdefault),
+    update = gateway.interp2app(W_DictMultiObject.descr_update),
+    )
+
+
 class DictStrategy(object):
-
     def __init__(self, space):
         self.space = space
 
@@ -172,7 +486,6 @@
         # it ends up taking n**2 time, because the next() calls below
         # will take longer and longer.  But all interesting strategies
         # provide a better one.
-        space = self.space
         iterator = self.iteritems(w_dict)
         w_key, w_value = iterator.next_item()
         self.delitem(w_dict, w_key)
@@ -196,8 +509,8 @@
     def view_as_kwargs(self, w_dict):
         return (None, None)
 
+
 class EmptyDictStrategy(DictStrategy):
-
     erase, unerase = rerased.new_erasing_pair("empty")
     erase = staticmethod(erase)
     unerase = staticmethod(unerase)
@@ -304,6 +617,7 @@
     def getiteritems(self, w_dict):
         return iter([(None, None)])
 
+
 # Iterator Implementation base classes
 
 def _new_next(TP):
@@ -311,7 +625,7 @@
         EMPTY = None
     else:
         EMPTY = None, None
-    
+
     def next(self):
         if self.dictimplementation is None:
             return EMPTY
@@ -375,7 +689,7 @@
         wrapvalue = lambda space, key : key
     else:
         wrapvalue = dictimpl.wrapvalue.im_func
-    
+
     class IterClassKeys(BaseKeyIterator):
         def __init__(self, space, strategy, impl):
             self.iterator = strategy.getiterkeys(impl)
@@ -427,11 +741,6 @@
 
 create_iterator_classes(EmptyDictStrategy)
 
-registerimplementation(W_DictMultiObject)
-
-# DictImplementation lattice
-# XXX fix me
-
 
 # concrete subclasses of the above
 
@@ -546,7 +855,6 @@
 
 
 class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
-
     erase, unerase = rerased.new_erasing_pair("object")
     erase = staticmethod(erase)
     unerase = staticmethod(unerase)
@@ -579,8 +887,8 @@
 
 create_iterator_classes(ObjectDictStrategy)
 
+
 class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
-
     erase, unerase = rerased.new_erasing_pair("string")
     erase = staticmethod(erase)
     unerase = staticmethod(unerase)
@@ -646,7 +954,6 @@
 
 
 class UnicodeDictStrategy(AbstractTypedStrategy, DictStrategy):
-
     erase, unerase = rerased.new_erasing_pair("unicode")
     erase = staticmethod(erase)
     unerase = staticmethod(unerase)
@@ -748,9 +1055,6 @@
 
 create_iterator_classes(IntDictStrategy)
 
-init_signature = Signature(['seq_or_map'], None, 'kwargs')
-init_defaults = [None]
-
 
 def update1(space, w_dict, w_data):
     if space.findattr(w_data, space.wrap("keys")) is None:
@@ -792,6 +1096,9 @@
         w_dict.setitem(w_key, w_value)
 
 
+init_signature = Signature(['seq_or_map'], None, 'kwargs')
+init_defaults = [None]
+
 def init_or_update(space, w_dict, __args__, funcname):
     w_src, w_kwds = __args__.parse_obj(
             None, funcname,
@@ -802,131 +1109,32 @@
     if space.is_true(w_kwds):
         update1(space, w_dict, w_kwds)
 
-def init__DictMulti(space, w_dict, __args__):
-    init_or_update(space, w_dict, __args__, 'dict')
-
-def dict_update__DictMulti(space, w_dict, __args__):
-    init_or_update(space, w_dict, __args__, 'dict.update')
-
-def getitem__DictMulti_ANY(space, w_dict, w_key):
-    w_value = w_dict.getitem(w_key)
-    if w_value is not None:
-        return w_value
-
-    w_missing_item = w_dict.missing_method(space, w_key)
-    if w_missing_item is not None:
-        return w_missing_item
-
-    space.raise_key_error(w_key)
-
-def setitem__DictMulti_ANY_ANY(space, w_dict, w_newkey, w_newvalue):
-    w_dict.setitem(w_newkey, w_newvalue)
-
-def delitem__DictMulti_ANY(space, w_dict, w_key):
-    try:
-        w_dict.delitem(w_key)
-    except KeyError:
-        space.raise_key_error(w_key)
-
-def len__DictMulti(space, w_dict):
-    return space.wrap(w_dict.length())
-
-def contains__DictMulti_ANY(space, w_dict, w_key):
-    return space.newbool(w_dict.getitem(w_key) is not None)
-
-def iter__DictMulti(space, w_dict):
-    return W_DictMultiIterKeysObject(space, w_dict.iterkeys())
-
-def eq__DictMulti_DictMulti(space, w_left, w_right):
-    if space.is_w(w_left, w_right):
-        return space.w_True
-
-    if w_left.length() != w_right.length():
-        return space.w_False
-    iteratorimplementation = w_left.iteritems()
+def characterize(space, w_a, w_b):
+    """ (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
+    iteratorimplementation = w_a.iteritems()
     while 1:
         w_key, w_val = iteratorimplementation.next_item()
         if w_key is None:
             break
-        w_rightval = w_right.getitem(w_key)
-        if w_rightval is None:
-            return space.w_False
-        if not space.eq_w(w_val, w_rightval):
-            return space.w_False
-    return space.w_True
-
-def dict_copy__DictMulti(space, w_self):
-    w_new = W_DictMultiObject.allocate_and_init_instance(space)
-    update1_dict_dict(space, w_new, w_self)
-    return w_new
-
-
-def dict_items__DictMulti(space, w_self):
-    return W_DictViewItemsObject(space, w_self)
-
-def dict_keys__DictMulti(space, w_self):
-    return W_DictViewKeysObject(space, w_self)
-    # XXX on default this is a fast path when keys are string, do we want to
-    # port it to py3k?
-    # return w_self.w_keys()
-
-def dict_values__DictMulti(space, w_self):
-    return W_DictViewValuesObject(space, w_self)
-
-def dict_iteritems__DictMulti(space, w_self):
-    return W_DictMultiIterItemsObject(space, w_self.iteritems())
-
-def dict_iterkeys__DictMulti(space, w_self):
-    return W_DictMultiIterKeysObject(space, w_self.iterkeys())
-
-def dict_itervalues__DictMulti(space, w_self):
-    return W_DictMultiIterValuesObject(space, w_self.itervalues())
-
-def dict_clear__DictMulti(space, w_self):
-    w_self.clear()
-
-def dict_get__DictMulti_ANY_ANY(space, w_dict, w_key, w_default):
-    w_value = w_dict.getitem(w_key)
-    if w_value is not None:
-        return w_value
-    else:
-        return w_default
-
-def dict_setdefault__DictMulti_ANY_ANY(space, w_dict, w_key, w_default):
-    return w_dict.setdefault(w_key, w_default)
-
-def dict_pop__DictMulti_ANY(space, w_dict, w_key, defaults_w):
-    len_defaults = len(defaults_w)
-    if len_defaults > 1:
-        raise operationerrfmt(space.w_TypeError,
-                              "pop expected at most 2 arguments, got %d",
-                              1 + len_defaults)
-    w_item = w_dict.getitem(w_key)
-    if w_item is None:
-        if len_defaults > 0:
-            return defaults_w[0]
-        else:
-            space.raise_key_error(w_key)
-    else:
-        w_dict.delitem(w_key)
-        return w_item
-
-def dict_popitem__DictMulti(space, w_dict):
-    try:
-        w_key, w_value = w_dict.popitem()
-    except KeyError:
-        raise OperationError(space.w_KeyError,
-                             space.wrap("popitem(): dictionary is empty"))
-    return space.newtuple([w_key, w_value])
+        if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, 
w_smallest_diff_a_key)):
+            w_bvalue = w_b.getitem(w_key)
+            if w_bvalue is None:
+                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
 
 
 # ____________________________________________________________
 # Iteration
 
-
-class W_BaseDictMultiIterObject(W_Object):
-    from pypy.objspace.std.dicttype import dictiter_typedef as typedef
-
+class W_BaseDictMultiIterObject(W_Root):
     _immutable_fields_ = ["iteratorimplementation"]
 
     ignore_for_isinstance_cache = True
@@ -935,177 +1143,199 @@
         w_self.space = space
         w_self.iteratorimplementation = iteratorimplementation
 
+    def descr_iter(self, space):
+        return self
+
+    def descr_length_hint(self, space):
+        return space.wrap(self.iteratorimplementation.length())
+
+    def descr_reduce(self, space):
+        """
+        This is a slightly special case of pickling.
+        Since iteration over a dict is a bit hairy,
+        we do the following:
+        - create a clone of the dict iterator
+        - run it to the original position
+        - collect all remaining elements into a list
+        At unpickling time, we just use that list
+        and create an iterator on it.
+        This is of course not the standard way.
+
+        XXX to do: remove this __reduce__ method and do
+        a registration with copy_reg, instead.
+        """
+        w_mod    = space.getbuiltinmodule('_pickle_support')
+        mod      = space.interp_w(MixedModule, w_mod)
+        new_inst = mod.get('dictiter_surrogate_new')
+        w_typeobj = space.gettypeobject(W_BaseDictMultiIterObject.typedef)
+
+        raise OperationError(
+            space.w_TypeError,
+            space.wrap("can't pickle dictionary-keyiterator objects"))
+        # XXXXXX get that working again
+
+        # we cannot call __init__ since we don't have the original dict
+        if isinstance(self, W_DictIter_Keys):
+            w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj)
+        elif isinstance(self, W_DictIter_Values):
+            w_clone = space.allocate_instance(W_DictIter_Values, w_typeobj)
+        elif isinstance(self, W_DictIter_Items):
+            w_clone = space.allocate_instance(W_DictIter_Items, w_typeobj)
+        else:
+            msg = "unsupported dictiter type '%s' during pickling" % (self,)
+            raise OperationError(space.w_TypeError, space.wrap(msg))
+        w_clone.space = space
+        w_clone.content = self.content
+        w_clone.len = self.len
+        w_clone.pos = 0
+        w_clone.setup_iterator()
+        # spool until we have the same pos
+        while w_clone.pos < self.pos:
+            w_obj = w_clone.next_entry()
+            w_clone.pos += 1
+        stuff = [w_clone.next_entry() for i in range(w_clone.pos, w_clone.len)]
+        w_res = space.newlist(stuff)
+        tup      = [
+            w_res
+        ]
+        w_ret = space.newtuple([new_inst, space.newtuple(tup)])
+        return w_ret
+
+
 class W_DictMultiIterKeysObject(W_BaseDictMultiIterObject):
-    pass
+    def descr_next(self, space):
+        iteratorimplementation = self.iteratorimplementation
+        w_key = iteratorimplementation.next_key()
+        if w_key is not None:
+            return w_key
+        raise OperationError(space.w_StopIteration, space.w_None)
 
 class W_DictMultiIterValuesObject(W_BaseDictMultiIterObject):
-    pass
+    def descr_next(self, space):
+        iteratorimplementation = self.iteratorimplementation
+        w_value = iteratorimplementation.next_value()
+        if w_value is not None:
+            return w_value
+        raise OperationError(space.w_StopIteration, space.w_None)
 
 class W_DictMultiIterItemsObject(W_BaseDictMultiIterObject):
-    pass
+    def descr_next(self, space):
+        iteratorimplementation = self.iteratorimplementation
+        w_key, w_value = iteratorimplementation.next_item()
+        if w_key is not None:
+            return space.newtuple([w_key, w_value])
+        raise OperationError(space.w_StopIteration, space.w_None)
 
-registerimplementation(W_DictMultiIterKeysObject)
-registerimplementation(W_DictMultiIterValuesObject)
-registerimplementation(W_DictMultiIterItemsObject)
+W_DictMultiIterItemsObject.typedef = StdTypeDef(
+    "dict_iteritems",
+    __iter__ = gateway.interp2app(W_DictMultiIterItemsObject.descr_iter),
+    next = gateway.interp2app(W_DictMultiIterItemsObject.descr_next),
+    __length_hint__ = 
gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint)
+    )
 
-def iter__DictMultiIterKeysObject(space, w_dictiter):
-    return w_dictiter
+W_DictMultiIterKeysObject.typedef = StdTypeDef(
+    "dict_iterkeys",
+    __iter__ = gateway.interp2app(W_DictMultiIterKeysObject.descr_iter),
+    next = gateway.interp2app(W_DictMultiIterKeysObject.descr_next),
+    __length_hint__ = 
gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint)
+    )
 
-def next__DictMultiIterKeysObject(space, w_dictiter):
-    iteratorimplementation = w_dictiter.iteratorimplementation
-    w_key = iteratorimplementation.next_key()
-    if w_key is not None:
-        return w_key
-    raise OperationError(space.w_StopIteration, space.w_None)
+W_DictMultiIterValuesObject.typedef = StdTypeDef(
+    "dict_itervalues",
+    __iter__ = gateway.interp2app(W_DictMultiIterValuesObject.descr_iter),
+    next = gateway.interp2app(W_DictMultiIterValuesObject.descr_next),
+    __length_hint__ = 
gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint)
+    )
 
-def iter__DictMultiIterValuesObject(space, w_dictiter):
-    return w_dictiter
-
-def next__DictMultiIterValuesObject(space, w_dictiter):
-    iteratorimplementation = w_dictiter.iteratorimplementation
-    w_value = iteratorimplementation.next_value()
-    if w_value is not None:
-        return w_value
-    raise OperationError(space.w_StopIteration, space.w_None)
-
-def iter__DictMultiIterItemsObject(space, w_dictiter):
-    return w_dictiter
-
-def next__DictMultiIterItemsObject(space, w_dictiter):
-    iteratorimplementation = w_dictiter.iteratorimplementation
-    w_key, w_value = iteratorimplementation.next_item()
-    if w_key is not None:
-        return space.newtuple([w_key, w_value])
-    raise OperationError(space.w_StopIteration, space.w_None)
 
 # ____________________________________________________________
 # Views
 
-class W_DictViewObject(W_Object):
+class W_DictViewObject(W_Root):
     def __init__(w_self, space, w_dict):
         w_self.w_dict = w_dict
 
-class W_DictViewKeysObject(W_DictViewObject):
-    from pypy.objspace.std.dicttype import dict_keys_typedef as typedef
-registerimplementation(W_DictViewKeysObject)
+    def descr_repr(self, space):
+        w_seq = space.call_function(space.w_list, self)
+        w_repr = space.repr(w_seq)
+        return space.wrap("%s(%s)" % (space.type(self).getname(space),
+                                      space.str_w(w_repr)))
+
+    def descr_eq(self, space, w_otherview):
+        if not space.eq_w(space.len(self), space.len(w_otherview)):
+            return space.w_False
+
+        w_iter = space.iter(self)
+        while True:
+            try:
+                w_item = space.next(w_iter)
+            except OperationError, e:
+                if not e.match(space, space.w_StopIteration):
+                    raise
+                break
+            if not space.is_true(space.contains(w_otherview, w_item)):
+                return space.w_False
+        return space.w_True
+
+    def descr_len(self, space):
+        return space.len(self.w_dict)
+
+    def descr_and(self, space, w_otherview):
+        w_set = space.call_function(space.w_set, self)
+        space.call_method(w_set, "intersection_update", w_otherview)
+        return w_set
+
+    def descr_or(self, space, w_otherview):
+        w_set = space.call_function(space.w_set, self)
+        space.call_method(w_set, "update", w_otherview)
+        return w_set
+
+    def descr_xor(self, space, w_otherview):
+        w_set = space.call_function(space.w_set, self)
+        space.call_method(w_set, "symmetric_difference_update", w_otherview)
+        return w_set
 
 class W_DictViewItemsObject(W_DictViewObject):
-    from pypy.objspace.std.dicttype import dict_items_typedef as typedef
-registerimplementation(W_DictViewItemsObject)
+    def descr_iter(self, space):
+        return W_DictMultiIterItemsObject(space, self.w_dict.iteritems())
+
+class W_DictViewKeysObject(W_DictViewObject):
+    def descr_iter(self, space):
+        return W_DictMultiIterKeysObject(space, self.w_dict.iterkeys())
 
 class W_DictViewValuesObject(W_DictViewObject):
-    from pypy.objspace.std.dicttype import dict_values_typedef as typedef
-registerimplementation(W_DictViewValuesObject)
+    def descr_iter(self, space):
+        return W_DictMultiIterValuesObject(space, self.w_dict.itervalues())
 
-def len__DictViewKeys(space, w_dictview):
-    return space.len(w_dictview.w_dict)
-len__DictViewItems = len__DictViewValues = len__DictViewKeys
+W_DictViewItemsObject.typedef = StdTypeDef(
+    "dict_items",
+    __repr__ = gateway.interp2app(W_DictViewItemsObject.descr_repr),
+    __eq__ = gateway.interp2app(W_DictViewItemsObject.descr_eq),
+    __len__ = gateway.interp2app(W_DictViewItemsObject.descr_len),
+    __iter__ = gateway.interp2app(W_DictViewItemsObject.descr_iter),
+    __and__ = gateway.interp2app(W_DictViewItemsObject.descr_and),
+    __or__ = gateway.interp2app(W_DictViewItemsObject.descr_or),
+    __xor__ = gateway.interp2app(W_DictViewItemsObject.descr_xor)
+    )
 
-def iter__DictViewKeys(space, w_dictview):
-    return dict_iterkeys__DictMulti(space, w_dictview.w_dict)
-def iter__DictViewItems(space, w_dictview):
-    return dict_iteritems__DictMulti(space, w_dictview.w_dict)
-def iter__DictViewValues(space, w_dictview):
-    return dict_itervalues__DictMulti(space, w_dictview.w_dict)
+W_DictViewKeysObject.typedef = StdTypeDef(
+    "dict_keys",
+    __repr__ = gateway.interp2app(W_DictViewKeysObject.descr_repr),
+    __eq__ = gateway.interp2app(W_DictViewKeysObject.descr_eq),
+    __len__ = gateway.interp2app(W_DictViewKeysObject.descr_len),
+    __iter__ = gateway.interp2app(W_DictViewKeysObject.descr_iter),
+    __and__ = gateway.interp2app(W_DictViewKeysObject.descr_and),
+    __or__ = gateway.interp2app(W_DictViewKeysObject.descr_or),
+    __xor__ = gateway.interp2app(W_DictViewKeysObject.descr_xor)
+    )
 
-def all_contained_in(space, w_dictview, w_otherview):
-    w_iter = space.iter(w_dictview)
-
-    while True:
-        try:
-            w_item = space.next(w_iter)
-        except OperationError, e:
-            if not e.match(space, space.w_StopIteration):
-                raise
-            break
-        if not space.is_true(space.contains(w_otherview, w_item)):
-            return space.w_False
-
-    return space.w_True
-
-def comparison_impl(fn):
-    opname = fn.func_name
-    types = ['DictViewKeys', 'DictViewItems', 'settypedef', 'frozensettypedef']
-    for lefttype in types:
-        for righttype in types:
-            fnname = '%s__%s_%s' % (opname, lefttype, righttype)
-            globals()[fnname] = fn
-    return fn
-
-@comparison_impl
-def eq(space, w_left, w_right):
-    if space.eq_w(space.len(w_left), space.len(w_right)):
-        return all_contained_in(space, w_left, w_right)
-    return space.w_False
-
-@comparison_impl
-def ne(space, w_left, w_right):
-    if not space.eq_w(space.len(w_left), space.len(w_right)):
-        return space.w_True
-    return space.not_(all_contained_in(space, w_left, w_right))
-
-@comparison_impl
-def lt(space, w_left, w_right):
-    if space.len_w(w_left) < space.len_w(w_right):
-        return all_contained_in(space, w_left, w_right)
-    return space.w_False
-
-@comparison_impl
-def le(space, w_left, w_right):
-    if space.len_w(w_left) <= space.len_w(w_right):
-        return all_contained_in(space, w_left, w_right)
-    return space.w_False
-
-@comparison_impl
-def gt(space, w_left, w_right):
-    if space.len_w(w_left) > space.len_w(w_right):
-        return all_contained_in(space, w_right, w_left)
-    return space.w_False
-
-@comparison_impl
-def ge(space, w_left, w_right):
-    if space.len_w(w_left) >= space.len_w(w_right):
-        return all_contained_in(space, w_right, w_left)
-    return space.w_False
-
-
-def repr__DictViewKeys(space, w_dictview):
-    typename = space.type(w_dictview).getname(space).decode('utf-8')
-    w_seq = space.call_function(space.w_list, w_dictview)
-    seq_repr = space.unicode_w(space.repr(w_seq))
-    return space.wrap(u"%s(%s)" % (typename, seq_repr))
-repr__DictViewItems  = repr__DictViewKeys
-repr__DictViewValues = repr__DictViewKeys
-
-
-def generate_setops():
-    OPLIST = [
-        ('and', 'intersection_update'),
-        ('or', 'update'),
-        ('xor', 'symmetric_difference_update'),
-        ('sub', 'difference_update'),
-        ]
-
-    for (opname, methodname) in OPLIST:
-        src = py.code.Source("""
-        def {opname}__DictViewKeys_ANY(space, w_dictview, w_other):
-            w_set = space.call_function(space.w_set, w_dictview)
-            space.call_method(w_set, '{methodname}', w_other)
-            return w_set
-
-        def {opname}__ANY_DictViewKeys(space, w_other, w_dictview):
-            w_set = space.call_function(space.w_set, w_other)
-            space.call_method(w_set, '{methodname}', w_dictview)
-            return w_set
-
-        {opname}__DictViewItems_ANY = {opname}__DictViewKeys_ANY
-        {opname}__ANY_DictViewItems = {opname}__ANY_DictViewKeys
-        """.format(opname=opname, methodname=methodname))
-        exec src.compile() in globals()
-
-generate_setops()
-
-# ____________________________________________________________
-
-from pypy.objspace.std import dicttype
-register_all(vars(), dicttype)
+W_DictViewValuesObject.typedef = StdTypeDef(
+    "dict_values",
+    __repr__ = gateway.interp2app(W_DictViewValuesObject.descr_repr),
+    __eq__ = gateway.interp2app(W_DictViewValuesObject.descr_eq),
+    __len__ = gateway.interp2app(W_DictViewValuesObject.descr_len),
+    __iter__ = gateway.interp2app(W_DictViewValuesObject.descr_iter),
+    __and__ = gateway.interp2app(W_DictViewValuesObject.descr_and),
+    __or__ = gateway.interp2app(W_DictViewValuesObject.descr_or),
+    __xor__ = gateway.interp2app(W_DictViewValuesObject.descr_xor)
+    )
diff --git a/pypy/objspace/std/dicttype.py b/pypy/objspace/std/dicttype.py
deleted file mode 100644
--- a/pypy/objspace/std/dicttype.py
+++ /dev/null
@@ -1,243 +0,0 @@
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.mixedmodule import MixedModule
-from pypy.interpreter import gateway
-from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
-from pypy.objspace.std.register_all import register_all
-
-dict_copy       = SMM('copy',          1,
-                      doc='D.copy() -> a shallow copy of D')
-dict_items      = SMM('items',         1,
-                      doc="D.items() -> a set-like object providing a view on 
D's item")
-dict_keys       = SMM('keys',          1,
-                      doc="D.keys() -> a set-like object providing a view on 
D's keys")
-dict_values     = SMM('values',        1,
-                      doc="D.values() -> an object providing a view on D's 
values")
-dict_clear      = SMM('clear',         1,
-                      doc='D.clear() -> None.  Remove all items from D.')
-dict_get        = SMM('get',           3, defaults=(None,),
-                      doc='D.get(k[,d]) -> D[k] if k in D, else d.  d defaults'
-                          ' to None.')
-dict_pop        = SMM('pop',           2, varargs_w=True,
-                      doc='D.pop(k[,d]) -> v, remove specified key and return'
-                          ' the corresponding value\nIf key is not found, d is'
-                          ' returned if given, otherwise KeyError is raised')
-dict_popitem    = SMM('popitem',       1,
-                      doc='D.popitem() -> (k, v), remove and return some (key,'
-                          ' value) pair as a\n2-tuple; but raise KeyError if D'
-                          ' is empty')
-dict_setdefault = SMM('setdefault',    3, defaults=(None,),
-                      doc='D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d'
-                          ' if k not in D')
-dict_update     = SMM('update',        1, general__args__=True,
-                      doc='D.update(E, **F) -> None.  Update D from E and F:'
-                          ' for k in E: D[k] = E[k]\n(if E has keys else: for'
-                          ' (k, v) in E: D[k] = v) then: for k in F: D[k] ='
-                          ' F[k]')
-dict_iteritems  = SMM('iteritems',     1,
-                      doc='D.iteritems() -> an iterator over the (key, value)'
-                          ' items of D')
-dict_iterkeys   = SMM('iterkeys',      1,
-                      doc='D.iterkeys() -> an iterator over the keys of D')
-dict_itervalues = SMM('itervalues',    1,
-                      doc='D.itervalues() -> an iterator over the values of D')
-dict_reversed   = SMM('__reversed__',      1)
-
-
-def dict_reversed__ANY(space, w_dict):
-    raise OperationError(space.w_TypeError, space.wrap('argument to reversed() 
must be a sequence'))
-
-register_all(vars(), globals())
-
-def descr_fromkeys(space, w_type, w_keys, w_fill=None):
-    from pypy.objspace.std.dictmultiobject import W_DictMultiObject
-    if w_fill is None:
-        w_fill = space.w_None
-    if space.is_w(w_type, space.w_dict):
-        w_dict = W_DictMultiObject.allocate_and_init_instance(space, w_type)
-
-        strlist = space.listview_str(w_keys)
-        if strlist is not None:
-            for key in strlist:
-                w_dict.setitem_str(key, w_fill)
-        else:
-            for w_key in space.listview(w_keys):
-                w_dict.setitem(w_key, w_fill)
-    else:
-        w_dict = space.call_function(w_type)
-        for w_key in space.listview(w_keys):
-            space.setitem(w_dict, w_key, w_fill)
-    return w_dict
-
-
-app = gateway.applevel('''
-    def dictrepr(currently_in_repr, d):
-        if len(d) == 0:
-            return "{}"
-        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 items() withut list 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 list(dict.items(d)):
-                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 descr_repr(space, w_dict):
-    ec = space.getexecutioncontext()
-    w_currently_in_repr = ec._py_repr
-    if w_currently_in_repr is None:
-        w_currently_in_repr = ec._py_repr = space.newdict()
-    return dictrepr(space, w_currently_in_repr, w_dict)
-
-
-# ____________________________________________________________
-
-def descr__new__(space, w_dicttype, __args__):
-    from pypy.objspace.std.dictmultiobject import W_DictMultiObject
-    w_obj = W_DictMultiObject.allocate_and_init_instance(space, w_dicttype)
-    return w_obj
-
-# ____________________________________________________________
-
-dict_typedef = StdTypeDef("dict",
-    __doc__ = '''dict() -> new empty dictionary.
-dict(mapping) -> new dictionary initialized from a mapping object\'s
-    (key, value) pairs.
-dict(seq) -> new dictionary initialized as if via:
-    d = {}
-    for k, v in seq:
-        d[k] = v
-dict(**kwargs) -> new dictionary initialized with the name=value pairs
-    in the keyword argument list.  For example:  dict(one=1, two=2)''',
-    __new__ = gateway.interp2app(descr__new__),
-    __hash__ = None,
-    __repr__ = gateway.interp2app(descr_repr),
-    fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True),
-    )
-dict_typedef.registermethods(globals())
-
-# ____________________________________________________________
-
-def descr_dictiter__length_hint__(space, w_self):
-    from pypy.objspace.std.dictmultiobject import W_BaseDictMultiIterObject
-    assert isinstance(w_self, W_BaseDictMultiIterObject)
-    return space.wrap(w_self.iteratorimplementation.length())
-
-
-def descr_dictiter__reduce__(w_self, space):
-    """
-    This is a slightly special case of pickling.
-    Since iteration over a dict is a bit hairy,
-    we do the following:
-    - create a clone of the dict iterator
-    - run it to the original position
-    - collect all remaining elements into a list
-    At unpickling time, we just use that list
-    and create an iterator on it.
-    This is of course not the standard way.
-
-    XXX to do: remove this __reduce__ method and do
-    a registration with copyreg, instead.
-    """
-    w_mod    = space.getbuiltinmodule('_pickle_support')
-    mod      = space.interp_w(MixedModule, w_mod)
-    new_inst = mod.get('dictiter_surrogate_new')
-    w_typeobj = space.gettypeobject(dictiter_typedef)
-
-    raise OperationError(
-        space.w_TypeError,
-        space.wrap("can't pickle dictionary-keyiterator objects"))
-    # XXXXXX get that working again
-
-    # we cannot call __init__ since we don't have the original dict
-    if isinstance(w_self, W_DictIter_Keys):
-        w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj)
-    elif isinstance(w_self, W_DictIter_Values):
-        w_clone = space.allocate_instance(W_DictIter_Values, w_typeobj)
-    elif isinstance(w_self, W_DictIter_Items):
-        w_clone = space.allocate_instance(W_DictIter_Items, w_typeobj)
-    else:
-        msg = "unsupported dictiter type '%s' during pickling" % (w_self, )
-        raise OperationError(space.w_TypeError, space.wrap(msg))
-    w_clone.space = space
-    w_clone.content = w_self.content
-    w_clone.len = w_self.len
-    w_clone.pos = 0
-    w_clone.setup_iterator()
-    # spool until we have the same pos
-    while w_clone.pos < w_self.pos:
-        w_obj = w_clone.next_entry()
-        w_clone.pos += 1
-    stuff = [w_clone.next_entry() for i in range(w_clone.pos, w_clone.len)]
-    w_res = space.newlist(stuff)
-    tup      = [
-        w_res
-    ]
-    w_ret = space.newtuple([new_inst, space.newtuple(tup)])
-    return w_ret
-
-# ____________________________________________________________
-
-
-dictiter_typedef = StdTypeDef("dictionaryiterator",
-    __length_hint__ = gateway.interp2app(descr_dictiter__length_hint__),
-    __reduce__      = gateway.interp2app(descr_dictiter__reduce__),
-    )
-
-# ____________________________________________________________
-# Dict views
-
-def descr_dictview_isdisjoin(space, w_self, w_other):
-    from pypy.objspace.std.dictmultiobject import W_DictViewObject
-    if w_self is w_other:
-        if space.len_w(w_self) == 0:
-            return space.w_True
-        else:
-            return space.w_False
-
-    # check whether w_other is a set-like object
-    if (space.isinstance_w(w_other, space.w_set) or
-        space.isinstance_w(w_other, space.w_frozenset) or
-        isinstance(w_other, W_DictViewObject)):
-        # if w_other is set-like and it's longer, we iterate over w_self
-        # instead
-        len_self = space.len_w(w_self)
-        len_other = space.len_w(w_other)
-        if len_other > len_self:
-            w_self, w_other = w_other, w_self
-
-    w_it = space.iter(w_other)
-    for w_item in space.iteriterable(w_it):
-        if space.is_true(space.contains(w_self, w_item)):
-            return space.w_False
-    return space.w_True
-
-
-dict_keys_typedef = StdTypeDef(
-    "dict_keys",
-    isdisjoint = gateway.interp2app(descr_dictview_isdisjoin),
-
-    )
-dict_keys_typedef.registermethods(globals())
-
-dict_items_typedef = StdTypeDef(
-    "dict_items",
-    isdisjoint = gateway.interp2app(descr_dictview_isdisjoin),
-    )
-
-dict_values_typedef = StdTypeDef(
-    "dict_values",
-    )
diff --git a/pypy/objspace/std/marshal_impl.py 
b/pypy/objspace/std/marshal_impl.py
--- a/pypy/objspace/std/marshal_impl.py
+++ b/pypy/objspace/std/marshal_impl.py
@@ -12,6 +12,7 @@
 from pypy.objspace.std.register_all import register_all
 from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_uint, intmask
 from pypy.objspace.std import model
+from pypy.objspace.std.dictmultiobject import W_DictMultiObject
 from pypy.interpreter.special import Ellipsis
 from pypy.interpreter.pycode import PyCode
 from pypy.interpreter import gateway, unicodehelper
@@ -24,7 +25,6 @@
 from pypy.objspace.std.floatobject   import W_FloatObject
 from pypy.objspace.std.tupleobject   import W_TupleObject
 from pypy.objspace.std.listobject    import W_ListObject
-from pypy.objspace.std.dictmultiobject    import W_DictMultiObject
 from pypy.objspace.std.stringobject  import W_StringObject
 from pypy.objspace.std.typeobject    import W_TypeObject
 from pypy.objspace.std.longobject    import W_LongObject, newlong
@@ -279,15 +279,18 @@
     return space.newlist(items_w)
 register(TYPE_LIST, unmarshal_List)
 
-def marshal_w__DictMulti(space, w_dict, m):
+def marshal_w_dict(space, w_dict, m):
+    if not isinstance(w_dict, W_DictMultiObject):
+        raise_exception(space, "unmarshallable object")
     m.start(TYPE_DICT)
     for w_tuple in w_dict.items():
         w_key, w_value = space.fixedview(w_tuple, 2)
         m.put_w_obj(w_key)
         m.put_w_obj(w_value)
     m.atom(TYPE_NULL)
+handled_by_any.append(('dict', marshal_w_dict))
 
-def unmarshal_DictMulti(space, u, tc):
+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.
@@ -299,7 +302,7 @@
         w_value = u.get_w_obj()
         space.setitem(w_dic, w_key, w_value)
     return w_dic
-register(TYPE_DICT, unmarshal_DictMulti)
+register(TYPE_DICT, unmarshal_dict)
 
 def unmarshal_NULL(self, u, tc):
     return None
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -40,7 +40,6 @@
             from pypy.objspace.std.complextype  import complex_typedef
             from pypy.objspace.std.tupletype  import tuple_typedef
             from pypy.objspace.std.listobject   import list_typedef
-            from pypy.objspace.std.dicttype   import dict_typedef
             from pypy.objspace.std.stringtype import str_typedef
             from pypy.objspace.std.bytearraytype import bytearray_typedef
             from pypy.objspace.std.typeobject   import type_typedef
@@ -80,6 +79,7 @@
 
         # not-multimethod based types
 
+        self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef)
         self.pythontypes.append(setobject.W_SetObject.typedef)
         self.pythontypes.append(setobject.W_FrozensetObject.typedef)
 
@@ -91,10 +91,6 @@
             floatobject.W_FloatObject: [],
             tupleobject.W_TupleObject: [],
             listobject.W_ListObject: [],
-            dictmultiobject.W_DictMultiObject: [],
-            dictmultiobject.W_DictMultiIterKeysObject: [],
-            dictmultiobject.W_DictMultiIterValuesObject: [],
-            dictmultiobject.W_DictMultiIterItemsObject: [],
             stringobject.W_StringObject: [],
             bytearrayobject.W_BytearrayObject: [],
             typeobject.W_TypeObject: [],
@@ -107,9 +103,6 @@
             iterobject.W_FastTupleIterObject: [],
             iterobject.W_ReverseSeqIterObject: [],
             unicodeobject.W_UnicodeObject: [],
-            dictmultiobject.W_DictViewKeysObject: [],
-            dictmultiobject.W_DictViewItemsObject: [],
-            dictmultiobject.W_DictViewValuesObject: [],
             pypy.interpreter.pycode.PyCode: [],
             pypy.interpreter.special.Ellipsis: [],
             }
@@ -327,9 +320,6 @@
             s += ' instance of %s' % self.w__class__
         return '<%s>' % s
 
-    def unwrap(self, space):
-        raise UnwrapError('cannot unwrap %r' % self)
-
 
 class UnwrapError(Exception):
     pass
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -276,10 +276,9 @@
 
     def unwrap(self, w_obj):
         """NOT_RPYTHON"""
-        if isinstance(w_obj, model.W_Object):
+        # _____ this code is here to support testing only _____
+        if isinstance(w_obj, W_Root):
             return w_obj.unwrap(self)
-        if isinstance(w_obj, W_Root):
-            return w_obj
         raise model.UnwrapError("cannot unwrap: %r" % w_obj)
 
     def newint(self, intval):
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py 
b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -3,8 +3,7 @@
 import py
 
 from pypy.objspace.std.dictmultiobject import (W_DictMultiObject,
-    setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, StringDictStrategy,
-    ObjectDictStrategy)
+    StringDictStrategy, ObjectDictStrategy)
 
 
 class TestW_DictObject(object):
@@ -398,6 +397,24 @@
             f = getattr(operator, op)
             raises(TypeError, f, d1, d2)
 
+    def test_other_rich_cmp(self):
+        d1 = {1: 2, 3: 4}
+        d2 = {1: 2, 3: 4}
+        d3 = {1: 2, 3: 5}
+        d4 = {1: 2}
+
+        assert d1 <= d2
+        assert d1 <= d3
+        assert not d1 <= d4
+
+        assert not d1 > d2
+        assert not d1 > d3
+        assert d1 > d4
+
+        assert d1 >= d2
+        assert not d1 >= d3
+        assert d1 >= d4
+
     def test_str_repr(self):
         assert '{}' == str({})
         assert '{1: 2}' == str({1: 2})
@@ -597,6 +614,9 @@
         assert isinstance(list({b'a': 1})[0], bytes)
 
 
+    def test_cmp_with_noncmp(self):
+        assert not {} > object()
+
 class AppTest_DictMultiObject(AppTest_DictObject):
 
     def test_emptydict_unhashable(self):
@@ -1127,10 +1147,10 @@
         pydict = {}
         for i in range(N):
             x = randint(-N, N)
-            setitem__DictMulti_ANY_ANY(self.space, d, x, i)
+            d.descr_setitem(self.space, x, i)
             pydict[x] = i
         for key, value in pydict.iteritems():
-            assert value == getitem__DictMulti_ANY(self.space, d, key)
+            assert value == d.descr_getitem(self.space, key)
 
 class BaseTestRDictImplementation:
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to