[Python-checkins] r77294 - in python/branches/py3k: Lib/test/test_descr.py Misc/NEWS Objects/complexobject.c

benjamin.peterson python-checkins at python.org
Mon Jan 4 02:10:28 CET 2010


Author: benjamin.peterson
Date: Mon Jan  4 02:10:28 2010
New Revision: 77294

Log:
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
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_descr.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/complexobject.c

Modified: python/branches/py3k/Lib/test/test_descr.py
==============================================================================
--- python/branches/py3k/Lib/test/test_descr.py	(original)
+++ python/branches/py3k/Lib/test/test_descr.py	Mon Jan  4 02:10:28 2010
@@ -1542,6 +1542,8 @@
             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 @@
              set(("__bases__",)), {}),
             ("__enter__", run_context, iden, set(), {"__exit__" : swallow}),
             ("__exit__", run_context, swallow, set(), {"__enter__" : iden}),
+            ("__complex__", complex, complex_num, set(), {}),
             ]
 
         class Checker(object):

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Jan  4 02:10:28 2010
@@ -12,6 +12,9 @@
 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.
 

Modified: python/branches/py3k/Objects/complexobject.c
==============================================================================
--- python/branches/py3k/Objects/complexobject.c	(original)
+++ python/branches/py3k/Objects/complexobject.c	Mon Jan  4 02:10:28 2010
@@ -262,12 +262,25 @@
 	}
 }
 
+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 @@
 	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 @@
 		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 @@
 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 @@
 		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;


More information about the Python-checkins mailing list