factor out __complex__ lookup code to fix another case
This commit is contained in:
parent
ecdae19fbe
commit
3694366af5
|
@ -280,12 +280,43 @@ PyComplex_ImagAsDouble(PyObject *op)
|
|||
}
|
||||
}
|
||||
|
||||
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,29 +329,7 @@ PyComplex_AsCComplex(PyObject *op)
|
|||
cv.real = -1.;
|
||||
cv.imag = 0.;
|
||||
|
||||
if (complex_str == NULL) {
|
||||
if (!(complex_str = PyString_InternFromString("__complex__")))
|
||||
return cv;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
newop = try_complex_special_method(op);
|
||||
|
||||
if (newop) {
|
||||
if (!PyComplex_Check(newop)) {
|
||||
|
@ -333,6 +342,9 @@ PyComplex_AsCComplex(PyObject *op)
|
|||
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 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
|
|||
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 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue