Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r87839:dd93cc36cc31
Date: 2016-10-17 14:34 +0200
http://bitbucket.org/pypy/pypy/changeset/dd93cc36cc31/

Log:    Manual graft of 6bff38772609

diff --git a/pypy/module/operator/test/test_operator.py 
b/pypy/module/operator/test/test_operator.py
--- a/pypy/module/operator/test/test_operator.py
+++ b/pypy/module/operator/test/test_operator.py
@@ -196,6 +196,13 @@
         assert operator.indexOf([4, 3, 2, 1], 3) == 1
         raises(ValueError, operator.indexOf, [4, 3, 2, 1], 0)
 
+    def test_index_int_subclass(self):
+        import operator
+        class myint(int):
+            def __index__(self):
+                return 13289
+        assert operator.index(myint(7)) == 7
+
     def test_compare_digest(self):
         import _operator as operator
 
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -470,6 +470,21 @@
     def isinstance(space, w_inst, w_type):
         return space.wrap(space.isinstance_w(w_inst, w_type))
 
+    def index(space, w_obj):
+        if space.isinstance_w(w_obj, space.w_int):
+            return w_obj
+        w_impl = space.lookup(w_obj, '__index__')
+        if w_impl is None:
+            raise oefmt(space.w_TypeError,
+                        "'%T' object cannot be interpreted as an integer",
+                        w_obj)
+        w_result = space.get_and_call_function(w_impl, w_obj)
+
+        if space.isinstance_w(w_result, space.w_int):
+            return w_result
+        raise oefmt(space.w_TypeError,
+                    "__index__ returned non-int (type %T)", w_result)
+
 
 # helpers
 
@@ -649,16 +664,12 @@
 # more of the above manually-coded operations as well)
 
 for targetname, specialname, checkerspec in [
-    ('index', '__index__', ("space.w_int",)),
     ('float', '__float__', ("space.w_float",))]:
 
     l = ["space.isinstance_w(w_result, %s)" % x
                 for x in checkerspec]
     checker = " or ".join(l)
-    if targetname == 'index':
-        msg = "'%%T' object cannot be interpreted as an integer"
-    else:
-        msg = "unsupported operand type for %(targetname)s(): '%%T'"
+    msg = "unsupported operand type for %(targetname)s(): '%%T'"
     msg = msg % locals()
     source = """if 1:
         def %(targetname)s(space, w_obj):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to