]> granicus.if.org Git - python/commitdiff
Merged revisions 77292-77293 via svnmerge from
authorBenjamin Peterson <benjamin@python.org>
Mon, 4 Jan 2010 01:10:28 +0000 (01:10 +0000)
committerBenjamin Peterson <benjamin@python.org>
Mon, 4 Jan 2010 01:10:28 +0000 (01:10 +0000)
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
........

Lib/test/test_descr.py
Misc/NEWS
Objects/complexobject.c

index c436eb641804f81451a04babc4f367c33d6cb50c..8e45bcf18a4a019a39192e7b20923965a3ba1465 100644 (file)
@@ -1542,6 +1542,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):
@@ -1575,6 +1577,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):
index 815e3922b9c3b06f05837f9cf1590a37c233763a..1f29728aefba0761cd07675490d7801bcd01134e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 1?
 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.
 
index 562e41f6f98e769d7de3259e9860fa9efcfa135f..73183676a657d4a00a03e8fd3840cfc50b528a53 100644 (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
 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 */
@@ -280,21 +293,7 @@ PyComplex_AsCComplex(PyObject *op)
        cv.real = -1.;
        cv.imag = 0.;
                
-       if (complex_str == NULL) {
-               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;
-               }
-       }
+       newop = try_complex_special_method(op);
 
        if (newop) {
                if (!PyComplex_Check(newop)) {
@@ -307,6 +306,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 {
@@ -880,13 +882,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;
@@ -921,26 +922,15 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
                return NULL;
        }
 
-       /* XXX Hack to support classes with __complex__ method */
-       if (complexstr == NULL) {
-               complexstr = PyUnicode_InternFromString("__complex__");
-               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;
+       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;