[pypy-svn] r49679 - in pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Dec 12 17:36:43 CET 2007


Author: cfbolz
Date: Wed Dec 12 17:36:42 2007
New Revision: 49679

Modified:
   pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py
   pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py
Log:
cmp


Modified: pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py
==============================================================================
--- pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py	(original)
+++ pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/interp_classobj.py	Wed Dec 12 17:36:42 2007
@@ -418,6 +418,50 @@
             space.w_TypeError,
             space.wrap("__nonzero__() should return an int"))
 
+    def descr_cmp(self, space, w_other): # do all the work here like CPython
+        w_a, w_b = _coerce_helper(space, self, w_other)
+        if w_a is None:
+            w_a = self
+            w_b = w_other
+        else:
+            if (not isinstance(w_a, W_InstanceObject) and
+                not isinstance(w_b, W_InstanceObject)):
+                return space.cmp(w_a, w_b)
+        if isinstance(w_a, W_InstanceObject):
+            w_func = w_a.getattr(space, space.wrap('__cmp__'), False)
+            if w_func is not None:
+                w_res = space.call_function(w_func, w_b)
+                try:
+                    res = space.int_w(w_res)
+                except OperationError, e:
+                    if e.match(space, space.w_TypeError):
+                        raise OperationError(
+                            space.w_TypeError,
+                            space.wrap("__cmp__ must return int"))
+                    raise
+                if res > 0:
+                    return space.wrap(1)
+                if res < 0:
+                    return space.wrap(-1)
+                return space.wrap(0)
+        if isinstance(w_b, W_InstanceObject):
+            w_func = w_b.getattr(space, space.wrap('__cmp__'), False)
+            if w_func is not None:
+                w_res = space.call_function(w_func, w_a)
+                try:
+                    res = space.int_w(w_res)
+                except OperationError, e:
+                    if e.match(space, space.w_TypeError):
+                        raise OperationError(
+                            space.w_TypeError,
+                            space.wrap("__cmp__ must return int"))
+                    raise
+                if res < 0:
+                    return space.wrap(1)
+                if res > 0:
+                    return space.wrap(-1)
+                return space.wrap(0)
+        return space.w_NotImplemented
 rawdict = {}
 
 # unary operations
@@ -485,6 +529,8 @@
                           unwrap_spec=['self', ObjSpace, Arguments]),
     __nonzero__ = interp2app(W_InstanceObject.descr_nonzero,
                              unwrap_spec=['self', ObjSpace]),
+    __cmp__ = interp2app(W_InstanceObject.descr_cmp,
+                         unwrap_spec=['self', ObjSpace, W_Root]),
     **rawdict
 )
 

Modified: pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py
==============================================================================
--- pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py	(original)
+++ pypy/branch/interplevel-oldstyle-classes/pypy/module/__builtin__/test/test_classobj.py	Wed Dec 12 17:36:42 2007
@@ -450,3 +450,31 @@
         assert a is a1
         assert a.l == [1, 2]
 
+    def test_cmp(self):
+        class A:
+            __metaclass__ = nclassobj
+            def __coerce__(self, other):
+                return (1, 2)
+        assert cmp(A(), 1) == -1
+        class A:
+            def __cmp__(self, other):
+                return 1
+        class B:
+            pass
+
+        a = A()
+        b = B()
+        assert cmp(a, b) == 1
+        assert cmp(b, a) == -1
+
+        class A:
+            def __cmp__(self, other):
+                return 1L
+        a = A()
+        assert cmp(a, b) == 1
+
+        class A:
+            def __cmp__(self, other):
+                return "hello?"
+        a = A()
+        raises(TypeError, cmp, a, b)



More information about the Pypy-commit mailing list