do correct lookup of the __complex__ method

This commit is contained in:
Benjamin Peterson 2010-01-04 00:43:01 +00:00
parent 37559a085b
commit ecdae19fbe
3 changed files with 20 additions and 8 deletions

View 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):

View File

@ -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.

View 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;