[Python-checkins] python/dist/src/Objects abstract.c, 2.135, 2.136 floatobject.c, 2.134, 2.135 intobject.c, 2.113, 2.114 longobject.c, 1.166, 1.167 object.c, 2.225, 2.226

bcannon at users.sourceforge.net bcannon at users.sourceforge.net
Tue Apr 26 05:46:03 CEST 2005


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16821/Objects

Modified Files:
	abstract.c floatobject.c intobject.c longobject.c object.c 
Log Message:
Make subclasses of int, long, complex, float, and unicode perform type
conversion using the proper magic slot (e.g., __int__()).  Also move conversion
code out of PyNumber_*() functions in the C API into the nb_* function.

Applied patch #1109424.  Thanks Walter Doewald.


Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.135
retrieving revision 2.136
diff -u -d -r2.135 -r2.136
--- abstract.c	18 Dec 2004 19:00:59 -0000	2.135
+++ abstract.c	26 Apr 2005 03:45:25 -0000	2.136
@@ -951,7 +951,19 @@
 		Py_INCREF(o);
 		return o;
 	}
-	if (PyInt_Check(o)) {
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_int) { /* This should include subclasses of int */
+		PyObject *res = m->nb_int(o);
+		if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+			PyErr_Format(PyExc_TypeError,
+				     "__int__ returned non-int (type %.200s)",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			return NULL;
+		}
+		return res;
+	}
+	if (PyInt_Check(o)) { /* A int subclass without nb_int */
 		PyIntObject *io = (PyIntObject*)o;
 		return PyInt_FromLong(io->ob_ival);
 	}
@@ -964,18 +976,6 @@
 					 PyUnicode_GET_SIZE(o),
 					 10);
 #endif
-	m = o->ob_type->tp_as_number;
-	if (m && m->nb_int) {
-		PyObject *res = m->nb_int(o);
-		if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
-			PyErr_Format(PyExc_TypeError,
-				     "__int__ returned non-int (type %.200s)",
-				     res->ob_type->tp_name);
-			Py_DECREF(res);
-			return NULL;
-		}
-		return res;
-	}
 	if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
 		return int_from_string((char*)buffer, buffer_len);
 
@@ -1010,11 +1010,19 @@
 
 	if (o == NULL)
 		return null_error();
-	if (PyLong_CheckExact(o)) {
-		Py_INCREF(o);
-		return o;
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_long) { /* This should include subclasses of long */
+		PyObject *res = m->nb_long(o);
+		if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+			PyErr_Format(PyExc_TypeError,
+				     "__long__ returned non-long (type %.200s)",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			return NULL;
+		}
+		return res;
 	}
-	if (PyLong_Check(o))
+	if (PyLong_Check(o)) /* A long subclass without nb_long */
 		return _PyLong_Copy((PyLongObject *)o);
 	if (PyString_Check(o))
 		/* need to do extra error checking that PyLong_FromString()
@@ -1030,18 +1038,6 @@
 					  PyUnicode_GET_SIZE(o),
 					  10);
 #endif
-	m = o->ob_type->tp_as_number;
-	if (m && m->nb_long) {
-		PyObject *res = m->nb_long(o);
-		if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
-			PyErr_Format(PyExc_TypeError,
-				     "__long__ returned non-long (type %.200s)",
-				     res->ob_type->tp_name);
-			Py_DECREF(res);
-			return NULL;
-		}
-		return res;
-	}
 	if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
 		return long_from_string(buffer, buffer_len);
 
@@ -1055,28 +1051,22 @@
 
 	if (o == NULL)
 		return null_error();
-	if (PyFloat_CheckExact(o)) {
-		Py_INCREF(o);
-		return o;
+	m = o->ob_type->tp_as_number;
+	if (m && m->nb_float) { /* This should include subclasses of float */
+		PyObject *res = m->nb_float(o);
+		if (res && !PyFloat_Check(res)) {
+			PyErr_Format(PyExc_TypeError,
+		          "__float__ returned non-float (type %.200s)",
+		          res->ob_type->tp_name);
+			Py_DECREF(res);
+			return NULL;
+		}
+		return res;
 	}
-	if (PyFloat_Check(o)) {
+	if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */
 		PyFloatObject *po = (PyFloatObject *)o;
 		return PyFloat_FromDouble(po->ob_fval);
 	}
-	if (!PyString_Check(o)) {
-		m = o->ob_type->tp_as_number;
-		if (m && m->nb_float) {
-			PyObject *res = m->nb_float(o);
-			if (res && !PyFloat_Check(res)) {
-				PyErr_Format(PyExc_TypeError,
-			          "__float__ returned non-float (type %.200s)",
-			          res->ob_type->tp_name);
-				Py_DECREF(res);
-				return NULL;
-			}
-			return res;
-		}
-	}
 	return PyFloat_FromString(o, NULL);
 }
 

Index: floatobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v
retrieving revision 2.134
retrieving revision 2.135
diff -u -d -r2.134 -r2.135
--- floatobject.c	23 Sep 2004 19:22:41 -0000	2.134
+++ floatobject.c	26 Apr 2005 03:45:25 -0000	2.135
@@ -926,7 +926,10 @@
 static PyObject *
 float_float(PyObject *v)
 {
-	Py_INCREF(v);
+	if (PyFloat_CheckExact(v))
+		Py_INCREF(v);
+	else
+		v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);
 	return v;
 }
 

Index: intobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v
retrieving revision 2.113
retrieving revision 2.114
diff -u -d -r2.113 -r2.114
--- intobject.c	25 Aug 2004 02:14:08 -0000	2.113
+++ intobject.c	26 Apr 2005 03:45:25 -0000	2.114
@@ -826,7 +826,10 @@
 static PyObject *
 int_int(PyIntObject *v)
 {
-	Py_INCREF(v);
+	if (PyInt_CheckExact(v))
+		Py_INCREF(v);
+	else
+		v = (PyIntObject *)PyInt_FromLong(v->ob_ival);
 	return (PyObject *)v;
 }
 

Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.166
retrieving revision 1.167
diff -u -d -r1.166 -r1.167
--- longobject.c	3 Mar 2005 12:26:34 -0000	1.166
+++ longobject.c	26 Apr 2005 03:45:25 -0000	1.167
@@ -2861,7 +2861,10 @@
 static PyObject *
 long_long(PyObject *v)
 {
-	Py_INCREF(v);
+	if (PyLong_CheckExact(v))
+		Py_INCREF(v);
+	else
+		v = _PyLong_Copy((PyLongObject *)v);
 	return v;
 }
 

Index: object.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.225
retrieving revision 2.226
diff -u -d -r2.225 -r2.226
--- object.c	23 Dec 2004 22:13:13 -0000	2.225
+++ object.c	26 Apr 2005 03:45:25 -0000	2.226
@@ -373,6 +373,8 @@
 PyObject_Unicode(PyObject *v)
 {
 	PyObject *res;
+	PyObject *func;
+	static PyObject *unicodestr;
 
 	if (v == NULL)
 		res = PyString_FromString("<NULL>");
@@ -380,35 +382,32 @@
 		Py_INCREF(v);
 		return v;
 	}
-	if (PyUnicode_Check(v)) {
-		/* For a Unicode subtype that's not a Unicode object,
-		   return a true Unicode object with the same data. */
-		return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v),
-					     PyUnicode_GET_SIZE(v));
+	/* XXX As soon as we have a tp_unicode slot, we should
+	   check this before trying the __unicode__
+	   method. */
+	if (unicodestr == NULL) {
+		unicodestr= PyString_InternFromString("__unicode__");
+		if (unicodestr == NULL)
+			return NULL;
+	}
+	func = PyObject_GetAttr(v, unicodestr);
+	if (func != NULL) {
+		res = PyEval_CallObject(func, (PyObject *)NULL);
+		Py_DECREF(func);
 	}
-	if (PyString_Check(v)) {
-		Py_INCREF(v);
-	    	res = v;
-    	}
 	else {
-		PyObject *func;
-		static PyObject *unicodestr;
-		/* XXX As soon as we have a tp_unicode slot, we should
-		       check this before trying the __unicode__
-		       method. */
-		if (unicodestr == NULL) {
-			unicodestr= PyString_InternFromString(
-						       "__unicode__");
-			if (unicodestr == NULL)
-				return NULL;
+		PyErr_Clear();
+		if (PyUnicode_Check(v)) {
+			/* For a Unicode subtype that's didn't overwrite __unicode__,
+			   return a true Unicode object with the same data. */
+			return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v),
+			                             PyUnicode_GET_SIZE(v));
 		}
-		func = PyObject_GetAttr(v, unicodestr);
-		if (func != NULL) {
-		    	res = PyEval_CallObject(func, (PyObject *)NULL);
-			Py_DECREF(func);
+		if (PyString_CheckExact(v)) {
+			Py_INCREF(v);
+			res = v;
 		}
 		else {
-			PyErr_Clear();
 			if (v->ob_type->tp_str != NULL)
 				res = (*v->ob_type->tp_str)(v);
 			else
@@ -424,7 +423,7 @@
 		if (str)
 			res = str;
 		else
-		    	return NULL;
+			return NULL;
 	}
 	return res;
 }



More information about the Python-checkins mailing list