[pypy-commit] pypy py3k: special case AttributeErrors when binding comparison descriptors

pjenvey noreply at buildbot.pypy.org
Tue Dec 11 20:56:31 CET 2012


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r59404:297567ccbd54
Date: 2012-12-11 11:30 -0800
http://bitbucket.org/pypy/pypy/changeset/297567ccbd54/

Log:	special case AttributeErrors when binding comparison descriptors

diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -548,6 +548,21 @@
 
     return func_with_new_name(binop_impl, "binop_%s_impl"%left.strip('_'))
 
+def _invoke_comparison(space, w_descr, w_obj1, w_obj2):
+    if w_descr is not None:
+        try:
+            w_impl = space.get(w_descr, w_obj1)
+        except OperationError as e:
+            # see testForExceptionsRaisedInInstanceGetattr2 in
+            # test_class
+            if not e.match(space, space.w_AttributeError):
+                raise
+        else:
+            w_res = space.call_function(w_impl, w_obj2)
+            if _check_notimplemented(space, w_res):
+                return w_res
+    return None
+
 def _make_comparison_impl(symbol, specialnames):
     left, right = specialnames
     op = getattr(operator, left)
@@ -568,10 +583,10 @@
             w_obj1, w_obj2 = w_obj2, w_obj1
             w_left_impl, w_right_impl = w_right_impl, w_left_impl
 
-        w_res = _invoke_binop(space, w_left_impl, w_obj1, w_obj2)
+        w_res = _invoke_comparison(space, w_left_impl, w_obj1, w_obj2)
         if w_res is not None:
             return w_res
-        w_res = _invoke_binop(space, w_right_impl, w_obj2, w_obj1)
+        w_res = _invoke_comparison(space, w_right_impl, w_obj2, w_obj1)
         if w_res is not None:
             return w_res
         #
diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -591,6 +591,19 @@
 
         raises(AttributeError, lambda: A().a)
 
+    def test_attribute_error2(self):
+        import operator
+        class A(object):
+            def __eq__(self, other):
+                raise AttributeError('doh')
+        raises(AttributeError, operator.eq, A(), A())
+
+        class E(object):
+            @property
+            def __eq__(self):
+                raise AttributeError('doh')
+        assert not (E() == E())
+
     def test_non_callable(self):
         meth = classmethod(1).__get__(1)
         raises(TypeError, meth)


More information about the pypy-commit mailing list