Mercurial > cpython-lru_cache-weakref
diff Objects/complexobject.c @ 58142:f7e09ba0cb55 legacy-trunk
factor out __complex__ lookup code to fix another case
| author | Benjamin Peterson <benjamin@python.org> |
|---|---|
| date | Mon, 04 Jan 2010 01:00:47 +0000 |
| parents | 4bc26a80e737 |
| children | c8ea75598fd6 |
line wrap: on
line diff
--- a/Objects/complexobject.c Mon Jan 04 00:43:01 2010 +0000 +++ b/Objects/complexobject.c Mon Jan 04 01:00:47 2010 +0000 @@ -280,12 +280,43 @@ } } +static PyObject * +try_complex_special_method(PyObject *op) { + PyObject *f; + static PyObject *complexstr; + + if (complexstr == NULL) { + complexstr = PyString_InternFromString("__complex__"); + if (complexstr == NULL) + return NULL; + } + if (PyInstance_Check(op)) { + f = PyObject_GetAttr(op, complexstr); + if (f == NULL) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) + PyErr_Clear(); + else + return NULL; + } + } + else { + f = _PyObject_LookupSpecial(op, "__complex__", &complexstr); + if (f == NULL && PyErr_Occurred()) + return NULL; + } + if (f != NULL) { + PyObject *res = PyObject_CallFunctionObjArgs(f, NULL); + Py_DECREF(f); + return res; + } + return NULL; +} + Py_complex PyComplex_AsCComplex(PyObject *op) { Py_complex cv; PyObject *newop = NULL; - static PyObject *complex_str = NULL; assert(op); /* If op is already of type PyComplex_Type, return its value */ @@ -298,30 +329,8 @@ cv.real = -1.; cv.imag = 0.; - if (complex_str == NULL) { - if (!(complex_str = PyString_InternFromString("__complex__"))) - return cv; - } + newop = try_complex_special_method(op); - if (PyInstance_Check(op)) { - /* this can go away in python 3000 */ - if (PyObject_HasAttr(op, complex_str)) { - newop = PyObject_CallMethod(op, "__complex__", NULL); - if (!newop) - return cv; - } - /* else try __float__ */ - } else { - PyObject *complexfunc; - complexfunc = _PyType_Lookup(op->ob_type, complex_str); - /* complexfunc is a borrowed reference */ - if (complexfunc) { - newop = PyObject_CallFunctionObjArgs(complexfunc, op, NULL); - if (!newop) - return cv; - } - } - if (newop) { if (!PyComplex_Check(newop)) { PyErr_SetString(PyExc_TypeError, @@ -333,6 +342,9 @@ Py_DECREF(newop); return cv; } + else if (PyErr_Occurred()) { + return cv; + } /* If neither of the above works, interpret op as a float giving the real part of the result, and fill in the imaginary part as 0. */ else { @@ -1073,13 +1085,12 @@ static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *r, *i, *tmp, *f; + PyObject *r, *i, *tmp; PyNumberMethods *nbr, *nbi = NULL; Py_complex cr, ci; int own_r = 0; int cr_is_complex = 0; int ci_is_complex = 0; - static PyObject *complexstr; static char *kwlist[] = {"real", "imag", 0}; r = Py_False; @@ -1114,32 +1125,15 @@ return NULL; } - if (complexstr == NULL) { - complexstr = PyString_InternFromString("__complex__"); - if (complexstr == NULL) - return NULL; - } - if (PyInstance_Check(r)) { - f = PyObject_GetAttr(r, complexstr); - if (f == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) - PyErr_Clear(); - else - return NULL; - } - } - else { - f = _PyObject_LookupSpecial(r, "__complex__", &complexstr); - if (f == NULL && PyErr_Occurred()) - return NULL; - } - if (f != NULL) { - r = PyObject_CallFunctionObjArgs(f, NULL); - Py_DECREF(f); - if (r == NULL) - return NULL; + tmp = try_complex_special_method(r); + if (tmp) { + r = tmp; own_r = 1; } + else if (PyErr_Occurred()) { + return NULL; + } + nbr = r->ob_type->tp_as_number; if (i != NULL) nbi = i->ob_type->tp_as_number;
