]> granicus.if.org Git - python/commitdiff
do correct lookup of the __complex__ method
authorBenjamin Peterson <benjamin@python.org>
Mon, 4 Jan 2010 00:43:01 +0000 (00:43 +0000)
committerBenjamin Peterson <benjamin@python.org>
Mon, 4 Jan 2010 00:43:01 +0000 (00:43 +0000)
Lib/test/test_descr.py
Misc/NEWS
Objects/complexobject.c

index 10b5af9250cf2f6ee7028e6573c3df756f0de3bd..418337b57a22fd85681c8da745f18b0e3a29ed08 100644 (file)
@@ -1691,6 +1691,8 @@ order (MRO) for bases """
             return []
         def zero(self):
             return 0
+        def complex_num(self):
+            return 1j
         def stop(self):
             raise StopIteration
         def return_true(self, thing=None):
@@ -1725,6 +1727,7 @@ order (MRO) for bases """
              set(("__bases__",)), {}),
             ("__enter__", run_context, iden, set(), {"__exit__" : swallow}),
             ("__exit__", run_context, swallow, set(), {"__enter__" : iden}),
+            ("__complex__", complex, complex_num, set(), {}),
             ]
 
         class Checker(object):
index cb39331b8c68429bef7ff8b2d4064ff46d9df495..06fb9eeb5c2e346bc985a6868e6df2d85de80c38 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 2?
 Core and Builtins
 -----------------
 
+- The __complex__ method is now looked up on the class of instances to make it
+  consistent with other special methods.
+
 - Issue #7462: Implement the stringlib fast search algorithm for the `rfind`,
   `rindex`, `rsplit` and `rpartition` methods.  Patch by Florent Xicluna.
 
index 298e262f86e1955a475b33ca9da91e7e28b160b3..60f2c15b77a5ac9d67e6957a8231b117e3599e1b 100644 (file)
@@ -1114,21 +1114,27 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
                return NULL;
        }
 
-       /* XXX Hack to support classes with __complex__ method */
        if (complexstr == NULL) {
                complexstr = PyString_InternFromString("__complex__");
                if (complexstr == NULL)
                        return NULL;
        }
-       f = PyObject_GetAttr(r, complexstr);
-       if (f == NULL)
-               PyErr_Clear();
+       if (PyInstance_Check(r)) {
+               f = PyObject_GetAttr(r, complexstr);
+               if (f == NULL) {
+                       if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                               PyErr_Clear();
+                       else
+                               return NULL;
+               }
+       }
        else {
-               PyObject *args = PyTuple_New(0);
-               if (args == NULL)
+               f = _PyObject_LookupSpecial(r, "__complex__", &complexstr);
+               if (f == NULL && PyErr_Occurred())
                        return NULL;
-               r = PyEval_CallObject(f, args);
-               Py_DECREF(args);
+       }
+       if (f != NULL) {
+               r = PyObject_CallFunctionObjArgs(f, NULL);
                Py_DECREF(f);
                if (r == NULL)
                        return NULL;