From ecdae19fbe9506fffe6616d86f3bbf4a1858f3e2 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 4 Jan 2010 00:43:01 +0000 Subject: do correct lookup of the __complex__ method --- Lib/test/test_descr.py | 3 +++ Misc/NEWS | 3 +++ Objects/complexobject.c | 22 ++++++++++++++-------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 10b5af9..418337b 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -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): diff --git a/Misc/NEWS b/Misc/NEWS index cb39331..06fb9ee 100644 --- 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. diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 298e262..60f2c15 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -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; -- cgit v0.12