Merged revisions 77292-77293 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r77292 | benjamin.peterson | 2010-01-03 18:43:01 -0600 (Sun, 03 Jan 2010) | 1 line

  do correct lookup of the __complex__ method
........
  r77293 | benjamin.peterson | 2010-01-03 19:00:47 -0600 (Sun, 03 Jan 2010) | 1 line

  factor out __complex__ lookup code to fix another case
........
This commit is contained in:
Benjamin Peterson 2010-01-04 01:10:28 +00:00
parent 66c741f5fb
commit aea4428fdc
3 changed files with 32 additions and 36 deletions

View File

@ -1542,6 +1542,8 @@ order (MRO) for bases """
return [] return []
def zero(self): def zero(self):
return 0 return 0
def complex_num(self):
return 1j
def stop(self): def stop(self):
raise StopIteration raise StopIteration
def return_true(self, thing=None): def return_true(self, thing=None):
@ -1575,6 +1577,7 @@ order (MRO) for bases """
set(("__bases__",)), {}), set(("__bases__",)), {}),
("__enter__", run_context, iden, set(), {"__exit__" : swallow}), ("__enter__", run_context, iden, set(), {"__exit__" : swallow}),
("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__exit__", run_context, swallow, set(), {"__enter__" : iden}),
("__complex__", complex, complex_num, set(), {}),
] ]
class Checker(object): class Checker(object):

View File

@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 1?
Core and Builtins 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`, - Issue #7462: Implement the stringlib fast search algorithm for the `rfind`,
`rindex`, `rsplit` and `rpartition` methods. Patch by Florent Xicluna. `rindex`, `rsplit` and `rpartition` methods. Patch by Florent Xicluna.

View File

@ -262,12 +262,25 @@ PyComplex_ImagAsDouble(PyObject *op)
} }
} }
static PyObject *
try_complex_special_method(PyObject *op) {
PyObject *f;
static PyObject *complexstr;
f = _PyObject_LookupSpecial(op, "__complex__", &complexstr);
if (f) {
PyObject *res = PyObject_CallFunctionObjArgs(f, NULL);
Py_DECREF(f);
return res;
}
return NULL;
}
Py_complex Py_complex
PyComplex_AsCComplex(PyObject *op) PyComplex_AsCComplex(PyObject *op)
{ {
Py_complex cv; Py_complex cv;
PyObject *newop = NULL; PyObject *newop = NULL;
static PyObject *complex_str = NULL;
assert(op); assert(op);
/* If op is already of type PyComplex_Type, return its value */ /* If op is already of type PyComplex_Type, return its value */
@ -280,21 +293,7 @@ PyComplex_AsCComplex(PyObject *op)
cv.real = -1.; cv.real = -1.;
cv.imag = 0.; cv.imag = 0.;
if (complex_str == NULL) { newop = try_complex_special_method(op);
if (!(complex_str = PyUnicode_FromString("__complex__")))
return cv;
}
{
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 (newop) {
if (!PyComplex_Check(newop)) { if (!PyComplex_Check(newop)) {
@ -307,6 +306,9 @@ PyComplex_AsCComplex(PyObject *op)
Py_DECREF(newop); Py_DECREF(newop);
return cv; return cv;
} }
else if (PyErr_Occurred()) {
return cv;
}
/* If neither of the above works, interpret op as a float giving the /* 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. */ real part of the result, and fill in the imaginary part as 0. */
else { else {
@ -880,13 +882,12 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
static PyObject * static PyObject *
complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
PyObject *r, *i, *tmp, *f; PyObject *r, *i, *tmp;
PyNumberMethods *nbr, *nbi = NULL; PyNumberMethods *nbr, *nbi = NULL;
Py_complex cr, ci; Py_complex cr, ci;
int own_r = 0; int own_r = 0;
int cr_is_complex = 0; int cr_is_complex = 0;
int ci_is_complex = 0; int ci_is_complex = 0;
static PyObject *complexstr;
static char *kwlist[] = {"real", "imag", 0}; static char *kwlist[] = {"real", "imag", 0};
r = Py_False; r = Py_False;
@ -921,26 +922,15 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
/* XXX Hack to support classes with __complex__ method */ tmp = try_complex_special_method(r);
if (complexstr == NULL) { if (tmp) {
complexstr = PyUnicode_InternFromString("__complex__"); r = tmp;
if (complexstr == NULL)
return NULL;
}
f = PyObject_GetAttr(r, complexstr);
if (f == NULL)
PyErr_Clear();
else {
PyObject *args = PyTuple_New(0);
if (args == NULL)
return NULL;
r = PyEval_CallObject(f, args);
Py_DECREF(args);
Py_DECREF(f);
if (r == NULL)
return NULL;
own_r = 1; own_r = 1;
} }
else if (PyErr_Occurred()) {
return NULL;
}
nbr = r->ob_type->tp_as_number; nbr = r->ob_type->tp_as_number;
if (i != NULL) if (i != NULL)
nbi = i->ob_type->tp_as_number; nbi = i->ob_type->tp_as_number;