[Python-checkins] python/dist/src/Objects abstract.c, 2.103.2.2, 2.103.2.3 bufferobject.c, 2.19.2.2, 2.19.2.3 classobject.c, 2.158.2.2, 2.158.2.3 complexobject.c, 2.62.2.2, 2.62.2.3 descrobject.c, 2.27.2.2, 2.27.2.3 dictobject.c, 2.126.2.2, 2.126.2.3 enumobject.c, 1.2.2.2, 1.2.2.3 fileobject.c, 2.164.2.2, 2.164.2.3 floatobject.c, 2.113.2.2, 2.113.2.3 funcobject.c, 2.55.2.4, 2.55.2.5 genobject.c, 1.4.4.1, 1.4.4.2 intobject.c, 2.84.2.2, 2.84.2.3 iterobject.c, 1.10.2.2, 1.10.2.3 listobject.c, 2.114.2.2, 2.114.2.3 listsort.txt, 1.6.10.1, 1.6.10.2 longobject.c, 1.118.2.2, 1.118.2.3 object.c, 2.179.2.3, 2.179.2.4 obmalloc.c, 2.45.2.2, 2.45.2.3 rangeobject.c, 2.41.2.2, 2.41.2.3 setobject.c, 1.31.4.1, 1.31.4.2 sliceobject.c, 2.15.2.2, 2.15.2.3 stringobject.c, 2.168.2.2, 2.168.2.3 tupleobject.c, 2.68.2.2, 2.68.2.3 typeobject.c, 2.157.2.3, 2.157.2.4 unicodeobject.c, 2.155.2.2, 2.155.2.3 weakrefobject.c, 1.9.2.2, 1.9.2.3

jhylton@users.sourceforge.net jhylton at users.sourceforge.net
Sun Oct 16 07:24:11 CEST 2005


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

Modified Files:
      Tag: ast-branch
	abstract.c bufferobject.c classobject.c complexobject.c 
	descrobject.c dictobject.c enumobject.c fileobject.c 
	floatobject.c funcobject.c genobject.c intobject.c 
	iterobject.c listobject.c listsort.txt longobject.c object.c 
	obmalloc.c rangeobject.c setobject.c sliceobject.c 
	stringobject.c tupleobject.c typeobject.c unicodeobject.c 
	weakrefobject.c 
Log Message:
Merge head to branch (for the last time)


Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.103.2.2
retrieving revision 2.103.2.3
diff -u -d -r2.103.2.2 -r2.103.2.3
--- abstract.c	7 Jan 2005 07:03:43 -0000	2.103.2.2
+++ abstract.c	16 Oct 2005 05:24:04 -0000	2.103.2.3
@@ -81,6 +81,31 @@
 }
 #define PyObject_Length PyObject_Size
 
+int
+_PyObject_LengthCue(PyObject *o)
+{
+	int rv = PyObject_Size(o);
+	if (rv != -1)
+		return rv;
+	if (PyErr_ExceptionMatches(PyExc_TypeError) ||
+	    PyErr_ExceptionMatches(PyExc_AttributeError)) {
+		PyObject *err_type, *err_value, *err_tb, *ro;
+
+		PyErr_Fetch(&err_type, &err_value, &err_tb);
+		ro = PyObject_CallMethod(o, "_length_cue", NULL);
+		if (ro != NULL) {
+			rv = (int)PyInt_AsLong(ro);
+			Py_DECREF(ro);
+			Py_XDECREF(err_type);
+			Py_XDECREF(err_value);
+			Py_XDECREF(err_tb);
+			return rv;
+		}
+		PyErr_Restore(err_type, err_value, err_tb);
+	}
+	return -1;
+}
+
 PyObject *
 PyObject_GetItem(PyObject *o, PyObject *key)
 {
@@ -951,7 +976,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 +1001,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 +1035,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 +1063,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 +1076,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);
 }
 
@@ -1409,8 +1424,13 @@
 		return NULL;
 
 	/* Guess result size and allocate space. */
-	n = PyObject_Size(v);
+	n = _PyObject_LengthCue(v);
 	if (n < 0) {
+		if (!PyErr_ExceptionMatches(PyExc_TypeError)  &&
+		    !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+			Py_DECREF(it);
+			return NULL;
+		}
 		PyErr_Clear();
 		n = 10;  /* arbitrary */
 	}
@@ -1807,7 +1827,9 @@
 PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
 {
 	va_list va;
-	PyObject *args, *func = 0, *retval;
+	PyObject *args = NULL;
+	PyObject *func = NULL;
+	PyObject *retval = NULL;
 
 	if (o == NULL || name == NULL)
 		return null_error();
@@ -1818,8 +1840,10 @@
 		return 0;
 	}
 
-	if (!PyCallable_Check(func))
-		return type_error("call of non-callable attribute");
+	if (!PyCallable_Check(func)) {
+		type_error("call of non-callable attribute"); 
+		goto exit;
+	}
 
 	if (format && *format) {
 		va_start(va, format);
@@ -1830,23 +1854,24 @@
 		args = PyTuple_New(0);
 
 	if (!args)
-		return NULL;
+		goto exit;
 
 	if (!PyTuple_Check(args)) {
 		PyObject *a;
 
 		a = PyTuple_New(1);
 		if (a == NULL)
-			return NULL;
+			goto exit;
 		if (PyTuple_SetItem(a, 0, args) < 0)
-			return NULL;
+			goto exit;
 		args = a;
 	}
 
 	retval = PyObject_Call(func, args, NULL);
 
-	Py_DECREF(args);
-	Py_DECREF(func);
+  exit:
+	Py_XDECREF(args);
+	Py_XDECREF(func);
 
 	return retval;
 }

Index: bufferobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/bufferobject.c,v
retrieving revision 2.19.2.2
retrieving revision 2.19.2.3
diff -u -d -r2.19.2.2 -r2.19.2.3
--- bufferobject.c	7 Jan 2005 07:03:44 -0000	2.19.2.2
+++ bufferobject.c	16 Oct 2005 05:24:04 -0000	2.19.2.3
@@ -192,7 +192,10 @@
 	int offset = 0;
 	int size = Py_END_OF_BUFFER;
 
-	if ( !PyArg_ParseTuple(args, "O|ii:buffer", &ob, &offset, &size) )
+	if (!_PyArg_NoKeywords("buffer()", kw))
+		return NULL;
+
+	if (!PyArg_ParseTuple(args, "O|ii:buffer", &ob, &offset, &size))
 	    return NULL;
 	return PyBuffer_FromObject(ob, offset, size);
 }

Index: classobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.158.2.2
retrieving revision 2.158.2.3
diff -u -d -r2.158.2.2 -r2.158.2.3
--- classobject.c	7 Jan 2005 07:03:44 -0000	2.158.2.2
+++ classobject.c	16 Oct 2005 05:24:04 -0000	2.158.2.3
@@ -1013,7 +1013,17 @@
 	if (res == NULL)
 		return -1;
 	if (PyInt_Check(res)) {
-		outcome = PyInt_AsLong(res);
+		long temp = PyInt_AsLong(res);
+		outcome = (int)temp;
+#if SIZEOF_INT < SIZEOF_LONG
+		/* Overflow check -- range of PyInt is more than C int */
+		if (outcome != temp) {
+			PyErr_SetString(PyExc_OverflowError,
+			 "__len__() should return 0 <= outcome < 2**31");
+			outcome = -1;
+		}
+		else
+#endif
 		if (outcome < 0)
 			PyErr_SetString(PyExc_ValueError,
 					"__len__() should return >= 0");
@@ -2208,6 +2218,12 @@
 	}
 	if (self == Py_None)
 		self = NULL;
+	if (self == NULL && classObj == NULL) {
+		PyErr_SetString(PyExc_TypeError,
+			"unbound methods must have non-NULL im_class");
+		return NULL;
+	}
+
 	return PyMethod_New(func, self, classObj);
 }
 
@@ -2480,7 +2496,7 @@
 	(getattrofunc)instancemethod_getattro,	/* tp_getattro */
 	PyObject_GenericSetAttr,		/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC  | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
 	instancemethod_doc,			/* tp_doc */
 	(traverseproc)instancemethod_traverse,	/* tp_traverse */
 	0,					/* tp_clear */

Index: complexobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v
retrieving revision 2.62.2.2
retrieving revision 2.62.2.3
diff -u -d -r2.62.2.2 -r2.62.2.3
--- complexobject.c	7 Jan 2005 07:03:44 -0000	2.62.2.2
+++ complexobject.c	16 Oct 2005 05:24:04 -0000	2.62.2.3
@@ -279,15 +279,12 @@
 		strncat(buf, "j", bufsz);
 	} else {
 		char re[64], im[64];
-		char *fmt;
+		/* Format imaginary part with sign, real part without */
 		PyOS_snprintf(format, 32, "%%.%ig", precision);
 		PyOS_ascii_formatd(re, 64, format, v->cval.real);
+		PyOS_snprintf(format, 32, "%%+.%ig", precision);
 		PyOS_ascii_formatd(im, 64, format, v->cval.imag);
-		if (v->cval.imag < 0.)
-			fmt = "(%s%sj)";
-		else
-			fmt = "(%s+%sj)";
-		PyOS_snprintf(buf, bufsz, fmt, re, im);
+		PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im);
 	}
 }
 

Index: descrobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v
retrieving revision 2.27.2.2
retrieving revision 2.27.2.3
diff -u -d -r2.27.2.2 -r2.27.2.3
--- descrobject.c	7 Jan 2005 07:03:45 -0000	2.27.2.2
+++ descrobject.c	16 Oct 2005 05:24:04 -0000	2.27.2.3
@@ -144,7 +144,7 @@
 		return res;
 	if (descr->d_getset->get != NULL)
 		return descr->d_getset->get(obj, descr->d_getset->closure);
-	PyErr_Format(PyExc_TypeError,
+	PyErr_Format(PyExc_AttributeError,
 		     "attribute '%.300s' of '%.100s' objects is not readable",
 		     descr_name((PyDescrObject *)descr),
 		     descr->d_type->tp_name);
@@ -199,7 +199,7 @@
 	if (descr->d_getset->set != NULL)
 		return descr->d_getset->set(obj, value,
 					    descr->d_getset->closure);
-	PyErr_Format(PyExc_TypeError,
+	PyErr_Format(PyExc_AttributeError,
 		     "attribute '%.300s' of '%.100s' objects is not writable",
 		     descr_name((PyDescrObject *)descr),
 		     descr->d_type->tp_name);

Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.126.2.2
retrieving revision 2.126.2.3
diff -u -d -r2.126.2.2 -r2.126.2.3
--- dictobject.c	7 Jan 2005 07:03:45 -0000	2.126.2.2
+++ dictobject.c	16 Oct 2005 05:24:04 -0000	2.126.2.3
@@ -113,7 +113,7 @@
 */
 
 /* Object used as dummy key to fill deleted entries */
-static PyObject *dummy; /* Initialized by first call to newdictobject() */
+static PyObject *dummy = NULL; /* Initialized by first call to newdictobject() */
 
 /* forward declarations */
 static dictentry *
@@ -400,8 +400,10 @@
 	else {
 		if (ep->me_key == NULL)
 			mp->ma_fill++;
-		else
-			Py_DECREF(ep->me_key);
+		else {
+			assert(ep->me_key == dummy);
+			Py_DECREF(dummy);
+		}
 		ep->me_key = key;
 		ep->me_hash = hash;
 		ep->me_value = value;
@@ -565,7 +567,7 @@
 	 */
 	if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2))
 		return 0;
-	return dictresize(mp, mp->ma_used*(mp->ma_used>50000 ? 2 : 4));
+	return dictresize(mp, (mp->ma_used>50000 ? mp->ma_used*2 : mp->ma_used*4));
 }
 
 int
@@ -1201,6 +1203,12 @@
 		if (other == mp || other->ma_used == 0)
 			/* a.update(a) or a.update({}); nothing to do */
 			return 0;
+		if (mp->ma_used == 0)
+			/* Since the target dict is empty, PyDict_GetItem()
+			 * always returns NULL.  Setting override to 1
+			 * skips the unnecessary test.
+			 */
+			override = 1;
 		/* Do one big resize at the start, rather than
 		 * incrementally resizing as we insert new items.  Expect
 		 * that there will be no (or few) overlapping keys.
@@ -1289,7 +1297,7 @@
 	if (PyDict_Merge(copy, o, 1) == 0)
 		return copy;
 	Py_DECREF(copy);
-	return copy;
+	return NULL;
 }
 
 int
@@ -2046,17 +2054,20 @@
 	PyObject_Del(di);
 }
 
-static int
+static PyObject *
 dictiter_len(dictiterobject *di)
 {
+	int len = 0;
 	if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
-		return di->len;
-	return 0;
+		len = di->len;
+	return PyInt_FromLong(len);
 }
 
-static PySequenceMethods dictiter_as_sequence = {
-	(inquiry)dictiter_len,		/* sq_length */
-	0,				/* sq_concat */
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef dictiter_methods[] = {
+	{"_length_cue", (PyCFunction)dictiter_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
 };
 
 static PyObject *dictiter_iternextkey(dictiterobject *di)
@@ -2112,7 +2123,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&dictiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -2128,6 +2139,8 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)dictiter_iternextkey,	/* tp_iternext */
+	dictiter_methods,			/* tp_methods */
+	0,
 };
 
 static PyObject *dictiter_iternextvalue(dictiterobject *di)
@@ -2183,7 +2196,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&dictiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -2199,6 +2212,8 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)dictiter_iternextvalue,	/* tp_iternext */
+	dictiter_methods,			/* tp_methods */
+	0,
 };
 
 static PyObject *dictiter_iternextitem(dictiterobject *di)
@@ -2268,7 +2283,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&dictiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -2284,4 +2299,6 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)dictiter_iternextitem,	/* tp_iternext */
+	dictiter_methods,			/* tp_methods */
+	0,
 };

Index: enumobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/enumobject.c,v
retrieving revision 1.2.2.2
retrieving revision 1.2.2.3
diff -u -d -r1.2.2.2 -r1.2.2.3
--- enumobject.c	7 Jan 2005 07:04:00 -0000	1.2.2.2
+++ enumobject.c	16 Oct 2005 05:24:04 -0000	1.2.2.3
@@ -239,23 +239,25 @@
 "\n"
 "Return a reverse iterator");
 
-static int
+static PyObject *
 reversed_len(reversedobject *ro)
 {
 	int position, seqsize;
 
 	if (ro->seq == NULL)
-		return 0;
+		return PyInt_FromLong(0);
 	seqsize = PySequence_Size(ro->seq);
 	if (seqsize == -1)
-		return -1;
+		return NULL;
 	position = ro->index + 1;
-	return (seqsize < position)  ?  0  :  position;
+	return PyInt_FromLong((seqsize < position)  ?  0  :  position);
 }
 
-static PySequenceMethods reversed_as_sequence = {
-	(inquiry)reversed_len,		/* sq_length */
-	0,				/* sq_concat */
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef reversediter_methods[] = {
+	{"_length_cue", (PyCFunction)reversed_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
 };
 
 PyTypeObject PyReversed_Type = {
@@ -272,7 +274,7 @@
 	0,                              /* tp_compare */
 	0,                              /* tp_repr */
 	0,                              /* tp_as_number */
-	&reversed_as_sequence,          /* tp_as_sequence */
+	0,				/* tp_as_sequence */
 	0,                              /* tp_as_mapping */
 	0,                              /* tp_hash */
 	0,                              /* tp_call */
@@ -289,7 +291,7 @@
 	0,                              /* tp_weaklistoffset */
 	PyObject_SelfIter,		/* tp_iter */
 	(iternextfunc)reversed_next,    /* tp_iternext */
-	0,				/* tp_methods */
+	reversediter_methods,		/* tp_methods */
 	0,                              /* tp_members */
 	0,                              /* tp_getset */
 	0,                              /* tp_base */

Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.164.2.2
retrieving revision 2.164.2.3
diff -u -d -r2.164.2.2 -r2.164.2.3
--- fileobject.c	7 Jan 2005 07:04:01 -0000	2.164.2.2
+++ fileobject.c	16 Oct 2005 05:24:04 -0000	2.164.2.3
@@ -128,6 +128,54 @@
 	return (PyObject *) f;
 }
 
+/* check for known incorrect mode strings - problem is, platforms are
+   free to accept any mode characters they like and are supposed to
+   ignore stuff they don't understand... write or append mode with
+   universal newline support is expressly forbidden by PEP 278. */
+/* zero return is kewl - one is un-kewl */
+static int
+check_the_mode(char *mode)
+{
+	unsigned int len = strlen(mode);
+
+	switch (len) {
+	case 0:
+		PyErr_SetString(PyExc_ValueError, "empty mode string");
+		return 1;
+
+	/* reject wU, aU */
+	case 2:
+		switch (mode[0]) {
+		case 'w':
+		case 'a':
+			if (mode[1] == 'U') {
+				PyErr_SetString(PyExc_ValueError,
+						"invalid mode string");
+				return 1;
+			}
+			break;
+		}
+		break;
+
+	/* reject w+U, a+U, wU+, aU+ */
+	case 3:
+		switch (mode[0]) {
+		case 'w':
+		case 'a':
+			if ((mode[1] == '+' && mode[2] == 'U') ||
+			    (mode[1] == 'U' && mode[2] == '+')) {
+				PyErr_SetString(PyExc_ValueError,
+						"invalid mode string");
+				return 1;
+			}
+			break;
+		}
+		break;
+	}
+
+	return 0;
+}
+
 static PyObject *
 open_the_file(PyFileObject *f, char *name, char *mode)
 {
@@ -142,6 +190,9 @@
 	assert(mode != NULL);
 	assert(f->f_fp == NULL);
 
+	if (check_the_mode(mode))
+		return NULL;
+
 	/* rexec.py can't stop a user from getting the file() constructor --
 	   all they have to do is get *any* file object f, and then do
 	   type(f).  Here we prevent them from doing damage with it. */

Index: floatobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v
retrieving revision 2.113.2.2
retrieving revision 2.113.2.3
diff -u -d -r2.113.2.2 -r2.113.2.3
--- floatobject.c	7 Jan 2005 07:04:01 -0000	2.113.2.2
+++ floatobject.c	16 Oct 2005 05:24:04 -0000	2.113.2.3
@@ -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;
 }
 
@@ -980,8 +983,139 @@
 	return Py_BuildValue("(d)", v->ob_fval);
 }
 
+/* this is for the benefit of the pack/unpack routines below */
+
+typedef enum {
+	unknown_format, ieee_big_endian_format, ieee_little_endian_format
+} float_format_type;
+
+static float_format_type double_format, float_format;
+static float_format_type detected_double_format, detected_float_format;
+
+static PyObject *
+float_getformat(PyTypeObject *v, PyObject* arg)
+{
+	char* s;
+	float_format_type r;
+
+	if (!PyString_Check(arg)) {
+		PyErr_Format(PyExc_TypeError,
+	     "__getformat__() argument must be string, not %.500s",
+			     arg->ob_type->tp_name);
+		return NULL;
+	}
+	s = PyString_AS_STRING(arg);
+	if (strcmp(s, "double") == 0) {
+		r = double_format;
+	}
+	else if (strcmp(s, "float") == 0) {
+		r = float_format;
+	}
+	else {
+		PyErr_SetString(PyExc_ValueError,
+				"__getformat__() argument 1 must be "
+				"'double' or 'float'");
+		return NULL;
+	}
+	
+	switch (r) {
+	case unknown_format:
+		return PyString_FromString("unknown");
+	case ieee_little_endian_format:
+		return PyString_FromString("IEEE, little-endian");
+	case ieee_big_endian_format:
+		return PyString_FromString("IEEE, big-endian");
+	default:
+		Py_FatalError("insane float_format or double_format");
+		return NULL;
+	}
+}
+
+PyDoc_STRVAR(float_getformat_doc,
+"float.__getformat__(typestr) -> string\n"
+"\n"
+"You probably don't want to use this function.  It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'.  This function returns whichever of\n"
+"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"
+"format of floating point numbers used by the C type named by typestr.");
+
+static PyObject *
+float_setformat(PyTypeObject *v, PyObject* args)
+{
+	char* typestr;
+	char* format;
+	float_format_type f;
+	float_format_type detected;
+	float_format_type *p;
+
+	if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))
+		return NULL;
+
+	if (strcmp(typestr, "double") == 0) {
+		p = &double_format;
+		detected = detected_double_format;
+	}
+	else if (strcmp(typestr, "float") == 0) {
+		p = &float_format;
+		detected = detected_float_format;
+	}
+	else {
+		PyErr_SetString(PyExc_ValueError,
+				"__setformat__() argument 1 must "
+				"be 'double' or 'float'");
+		return NULL;
+	}
+	
+	if (strcmp(format, "unknown") == 0) {
+		f = unknown_format;
+	}
+	else if (strcmp(format, "IEEE, little-endian") == 0) {
+		f = ieee_little_endian_format;
+	}
+	else if (strcmp(format, "IEEE, big-endian") == 0) {
+		f = ieee_big_endian_format;
+	}
+	else {
+		PyErr_SetString(PyExc_ValueError,
+				"__setformat__() argument 2 must be "
+				"'unknown', 'IEEE, little-endian' or "
+				"'IEEE, big-endian'");
+		return NULL;
+
+	}
+
+	if (f != unknown_format && f != detected) {
+		PyErr_Format(PyExc_ValueError,
+			     "can only set %s format to 'unknown' or the "
+			     "detected platform value", typestr);
+		return NULL;
+	}
+
+	*p = f;
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(float_setformat_doc,
+"float.__setformat__(typestr, fmt) -> None\n"
+"\n"
+"You probably don't want to use this function.  It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'.  fmt must be one of 'unknown',\n"
+"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n"
+"one of the latter two if it appears to match the underlying C reality.\n"
+"\n"
+"Overrides the automatic determination of C-level floating point type.\n"
+"This affects how floats are converted to and from binary strings.");
+
 static PyMethodDef float_methods[] = {
 	{"__getnewargs__",	(PyCFunction)float_getnewargs,	METH_NOARGS},
+	{"__getformat__",	(PyCFunction)float_getformat,	
+	 METH_O|METH_CLASS,		float_getformat_doc},
+	{"__setformat__",	(PyCFunction)float_setformat,	
+	 METH_VARARGS|METH_CLASS,	float_setformat_doc},
 	{NULL,		NULL}		/* sentinel */
 };
 
@@ -1076,6 +1210,56 @@
 };
 
 void
+_PyFloat_Init(void)
+{
+	/* We attempt to determine if this machine is using IEEE
+	   floating point formats by peering at the bits of some
+	   carefully chosen values.  If it looks like we are on an
+	   IEEE platform, the float packing/unpacking routines can
+	   just copy bits, if not they resort to arithmetic & shifts
+	   and masks.  The shifts & masks approach works on all finite
+	   values, but what happens to infinities, NaNs and signed
+	   zeroes on packing is an accident, and attempting to unpack
+	   a NaN or an infinity will raise an exception.
+
+	   Note that if we're on some whacked-out platform which uses
+	   IEEE formats but isn't strictly little-endian or big-
+	   endian, we will fall back to the portable shifts & masks
+	   method. */
+
+#if SIZEOF_DOUBLE == 8
+	{
+		double x = 9006104071832581.0;
+		if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
+			detected_double_format = ieee_big_endian_format;
+		else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
+			detected_double_format = ieee_little_endian_format;
+		else 
+			detected_double_format = unknown_format;
+	}
+#else
+	detected_double_format = unknown_format;
+#endif
+
+#if SIZEOF_FLOAT == 4
+	{
+		float y = 16711938.0;
+		if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
+			detected_float_format = ieee_big_endian_format;
+		else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
+			detected_float_format = ieee_little_endian_format;
+		else 
+			detected_float_format = unknown_format;
+	}
+#else
+	detected_float_format = unknown_format;
+#endif
+
+	double_format = detected_double_format;
+	float_format = detected_float_format;
+}
+
+void
 PyFloat_Fini(void)
 {
 	PyFloatObject *p;
@@ -1162,306 +1346,395 @@
 int
 _PyFloat_Pack4(double x, unsigned char *p, int le)
 {
-	unsigned char sign;
-	int e;
-	double f;
-	unsigned int fbits;
-	int incr = 1;
-
-	if (le) {
-		p += 3;
-		incr = -1;
-	}
+	if (float_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		double f;
+		unsigned int fbits;
+		int incr = 1;
 
-	if (x < 0) {
-		sign = 1;
-		x = -x;
-	}
-	else
-		sign = 0;
+		if (le) {
+			p += 3;
+			incr = -1;
+		}
 
-	f = frexp(x, &e);
+		if (x < 0) {
+			sign = 1;
+			x = -x;
+		}
+		else
+			sign = 0;
 
-	/* Normalize f to be in the range [1.0, 2.0) */
-	if (0.5 <= f && f < 1.0) {
-		f *= 2.0;
-		e--;
-	}
-	else if (f == 0.0)
-		e = 0;
-	else {
-		PyErr_SetString(PyExc_SystemError,
-				"frexp() result out of range");
-		return -1;
-	}
+		f = frexp(x, &e);
 
-	if (e >= 128)
-		goto Overflow;
-	else if (e < -126) {
-		/* Gradual underflow */
-		f = ldexp(f, 126 + e);
-		e = 0;
-	}
-	else if (!(e == 0 && f == 0.0)) {
-		e += 127;
-		f -= 1.0; /* Get rid of leading 1 */
-	}
+		/* Normalize f to be in the range [1.0, 2.0) */
+		if (0.5 <= f && f < 1.0) {
+			f *= 2.0;
+			e--;
+		}
+		else if (f == 0.0)
+			e = 0;
+		else {
+			PyErr_SetString(PyExc_SystemError,
+					"frexp() result out of range");
+			return -1;
+		}
 
-	f *= 8388608.0; /* 2**23 */
-	fbits = (unsigned int)(f + 0.5); /* Round */
-	assert(fbits <= 8388608);
-	if (fbits >> 23) {
-		/* The carry propagated out of a string of 23 1 bits. */
-		fbits = 0;
-		++e;
-		if (e >= 255)
+		if (e >= 128)
 			goto Overflow;
-	}
+		else if (e < -126) {
+			/* Gradual underflow */
+			f = ldexp(f, 126 + e);
+			e = 0;
+		}
+		else if (!(e == 0 && f == 0.0)) {
+			e += 127;
+			f -= 1.0; /* Get rid of leading 1 */
+		}
 
-	/* First byte */
-	*p = (sign << 7) | (e >> 1);
-	p += incr;
+		f *= 8388608.0; /* 2**23 */
+		fbits = (unsigned int)(f + 0.5); /* Round */
+		assert(fbits <= 8388608);
+		if (fbits >> 23) {
+			/* The carry propagated out of a string of 23 1 bits. */
+			fbits = 0;
+			++e;
+			if (e >= 255)
+				goto Overflow;
+		}
 
-	/* Second byte */
-	*p = (char) (((e & 1) << 7) | (fbits >> 16));
-	p += incr;
+		/* First byte */
+		*p = (sign << 7) | (e >> 1);
+		p += incr;
 
-	/* Third byte */
-	*p = (fbits >> 8) & 0xFF;
-	p += incr;
+		/* Second byte */
+		*p = (char) (((e & 1) << 7) | (fbits >> 16));
+		p += incr;
 
-	/* Fourth byte */
-	*p = fbits & 0xFF;
+		/* Third byte */
+		*p = (fbits >> 8) & 0xFF;
+		p += incr;
 
-	/* Done */
-	return 0;
+		/* Fourth byte */
+		*p = fbits & 0xFF;
 
- Overflow:
-	PyErr_SetString(PyExc_OverflowError,
-			"float too large to pack with f format");
-	return -1;
+		/* Done */
+		return 0;
+
+	  Overflow:
+		PyErr_SetString(PyExc_OverflowError,
+				"float too large to pack with f format");
+		return -1;
+	}
+	else {
+		float y = (float)x;
+		const char *s = (char*)&y;
+		int i, incr = 1;
+
+		if ((float_format == ieee_little_endian_format && !le)
+		    || (float_format == ieee_big_endian_format && le)) {
+			p += 3;
+			incr = -1;
+		}
+		
+		for (i = 0; i < 4; i++) {
+			*p = *s++;
+			p += incr;
+		}
+		return 0;
+	}
 }
 
 int
 _PyFloat_Pack8(double x, unsigned char *p, int le)
 {
-	unsigned char sign;
-	int e;
-	double f;
-	unsigned int fhi, flo;
-	int incr = 1;
+	if (double_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		double f;
+		unsigned int fhi, flo;
+		int incr = 1;
 
-	if (le) {
-		p += 7;
-		incr = -1;
-	}
+		if (le) {
+			p += 7;
+			incr = -1;
+		}
 
-	if (x < 0) {
-		sign = 1;
-		x = -x;
-	}
-	else
-		sign = 0;
+		if (x < 0) {
+			sign = 1;
+			x = -x;
+		}
+		else
+			sign = 0;
 
-	f = frexp(x, &e);
+		f = frexp(x, &e);
 
-	/* Normalize f to be in the range [1.0, 2.0) */
-	if (0.5 <= f && f < 1.0) {
-		f *= 2.0;
-		e--;
-	}
-	else if (f == 0.0)
-		e = 0;
-	else {
-		PyErr_SetString(PyExc_SystemError,
-				"frexp() result out of range");
-		return -1;
-	}
+		/* Normalize f to be in the range [1.0, 2.0) */
+		if (0.5 <= f && f < 1.0) {
+			f *= 2.0;
+			e--;
+		}
+		else if (f == 0.0)
+			e = 0;
+		else {
+			PyErr_SetString(PyExc_SystemError,
+					"frexp() result out of range");
+			return -1;
+		}
 
-	if (e >= 1024)
-		goto Overflow;
-	else if (e < -1022) {
-		/* Gradual underflow */
-		f = ldexp(f, 1022 + e);
-		e = 0;
-	}
-	else if (!(e == 0 && f == 0.0)) {
-		e += 1023;
-		f -= 1.0; /* Get rid of leading 1 */
-	}
+		if (e >= 1024)
+			goto Overflow;
+		else if (e < -1022) {
+			/* Gradual underflow */
+			f = ldexp(f, 1022 + e);
+			e = 0;
+		}
+		else if (!(e == 0 && f == 0.0)) {
+			e += 1023;
+			f -= 1.0; /* Get rid of leading 1 */
+		}
 
-	/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
-	f *= 268435456.0; /* 2**28 */
-	fhi = (unsigned int)f; /* Truncate */
-	assert(fhi < 268435456);
+		/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
+		f *= 268435456.0; /* 2**28 */
+		fhi = (unsigned int)f; /* Truncate */
+		assert(fhi < 268435456);
 
-	f -= (double)fhi;
-	f *= 16777216.0; /* 2**24 */
-	flo = (unsigned int)(f + 0.5); /* Round */
-	assert(flo <= 16777216);
-	if (flo >> 24) {
-		/* The carry propagated out of a string of 24 1 bits. */
-		flo = 0;
-		++fhi;
-		if (fhi >> 28) {
-			/* And it also progagated out of the next 28 bits. */
-			fhi = 0;
-			++e;
-			if (e >= 2047)
-				goto Overflow;
+		f -= (double)fhi;
+		f *= 16777216.0; /* 2**24 */
+		flo = (unsigned int)(f + 0.5); /* Round */
+		assert(flo <= 16777216);
+		if (flo >> 24) {
+			/* The carry propagated out of a string of 24 1 bits. */
+			flo = 0;
+			++fhi;
+			if (fhi >> 28) {
+				/* And it also progagated out of the next 28 bits. */
+				fhi = 0;
+				++e;
+				if (e >= 2047)
+					goto Overflow;
+			}
 		}
-	}
 
-	/* First byte */
-	*p = (sign << 7) | (e >> 4);
-	p += incr;
+		/* First byte */
+		*p = (sign << 7) | (e >> 4);
+		p += incr;
 
-	/* Second byte */
-	*p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
-	p += incr;
+		/* Second byte */
+		*p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
+		p += incr;
 
-	/* Third byte */
-	*p = (fhi >> 16) & 0xFF;
-	p += incr;
+		/* Third byte */
+		*p = (fhi >> 16) & 0xFF;
+		p += incr;
 
-	/* Fourth byte */
-	*p = (fhi >> 8) & 0xFF;
-	p += incr;
+		/* Fourth byte */
+		*p = (fhi >> 8) & 0xFF;
+		p += incr;
 
-	/* Fifth byte */
-	*p = fhi & 0xFF;
-	p += incr;
+		/* Fifth byte */
+		*p = fhi & 0xFF;
+		p += incr;
 
-	/* Sixth byte */
-	*p = (flo >> 16) & 0xFF;
-	p += incr;
+		/* Sixth byte */
+		*p = (flo >> 16) & 0xFF;
+		p += incr;
 
-	/* Seventh byte */
-	*p = (flo >> 8) & 0xFF;
-	p += incr;
+		/* Seventh byte */
+		*p = (flo >> 8) & 0xFF;
+		p += incr;
 
-	/* Eighth byte */
-	*p = flo & 0xFF;
-	p += incr;
+		/* Eighth byte */
+		*p = flo & 0xFF;
+		p += incr;
 
-	/* Done */
-	return 0;
+		/* Done */
+		return 0;
 
- Overflow:
-	PyErr_SetString(PyExc_OverflowError,
-			"float too large to pack with d format");
-	return -1;
+	  Overflow:
+		PyErr_SetString(PyExc_OverflowError,
+				"float too large to pack with d format");
+		return -1;
+	}
+	else {
+		const char *s = (char*)&x;
+		int i, incr = 1;
+
+		if ((double_format == ieee_little_endian_format && !le)
+		    || (double_format == ieee_big_endian_format && le)) {
+			p += 7;
+			incr = -1;
+		}
+		
+		for (i = 0; i < 8; i++) {
+			*p = *s++;
+			p += incr;
+		}
+		return 0;
+	}
 }
 
 double
 _PyFloat_Unpack4(const unsigned char *p, int le)
 {
-	unsigned char sign;
-	int e;
-	unsigned int f;
-	double x;
-	int incr = 1;
+	if (float_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		unsigned int f;
+		double x;
+		int incr = 1;
 
-	if (le) {
-		p += 3;
-		incr = -1;
-	}
+		if (le) {
+			p += 3;
+			incr = -1;
+		}
 
-	/* First byte */
-	sign = (*p >> 7) & 1;
-	e = (*p & 0x7F) << 1;
-	p += incr;
+		/* First byte */
+		sign = (*p >> 7) & 1;
+		e = (*p & 0x7F) << 1;
+		p += incr;
 
-	/* Second byte */
-	e |= (*p >> 7) & 1;
-	f = (*p & 0x7F) << 16;
-	p += incr;
+		/* Second byte */
+		e |= (*p >> 7) & 1;
+		f = (*p & 0x7F) << 16;
+		p += incr;
 
-	/* Third byte */
-	f |= *p << 8;
-	p += incr;
+		if (e == 255) {
+			PyErr_SetString(
+				PyExc_ValueError,
+				"can't unpack IEEE 754 special value "
+				"on non-IEEE platform");
+			return -1;
+		}
 
-	/* Fourth byte */
-	f |= *p;
+		/* Third byte */
+		f |= *p << 8;
+		p += incr;
 
-	x = (double)f / 8388608.0;
+		/* Fourth byte */
+		f |= *p;
 
-	/* XXX This sadly ignores Inf/NaN issues */
-	if (e == 0)
-		e = -126;
-	else {
-		x += 1.0;
-		e -= 127;
-	}
-	x = ldexp(x, e);
+		x = (double)f / 8388608.0;
 
-	if (sign)
-		x = -x;
+		/* XXX This sadly ignores Inf/NaN issues */
+		if (e == 0)
+			e = -126;
+		else {
+			x += 1.0;
+			e -= 127;
+		}
+		x = ldexp(x, e);
 
-	return x;
+		if (sign)
+			x = -x;
+
+		return x;
+	}
+	else {
+		if ((float_format == ieee_little_endian_format && !le)
+		    || (float_format == ieee_big_endian_format && le)) {
+			char buf[8];
+			char *d = &buf[3];
+			int i;
+
+			for (i = 0; i < 4; i++) {
+				*d-- = *p++;
+			}
+			return *(float*)&buf[0];
+		}
+		else {
+			return *(float*)p;
+		}
+	}		
 }
 
 double
 _PyFloat_Unpack8(const unsigned char *p, int le)
 {
-	unsigned char sign;
-	int e;
-	unsigned int fhi, flo;
-	double x;
-	int incr = 1;
+	if (double_format == unknown_format) {
+		unsigned char sign;
+		int e;
+		unsigned int fhi, flo;
+		double x;
+		int incr = 1;
 
-	if (le) {
-		p += 7;
-		incr = -1;
-	}
+		if (le) {
+			p += 7;
+			incr = -1;
+		}
 
-	/* First byte */
-	sign = (*p >> 7) & 1;
-	e = (*p & 0x7F) << 4;
-	p += incr;
+		/* First byte */
+		sign = (*p >> 7) & 1;
+		e = (*p & 0x7F) << 4;
+		
+		p += incr;
 
-	/* Second byte */
-	e |= (*p >> 4) & 0xF;
-	fhi = (*p & 0xF) << 24;
-	p += incr;
+		/* Second byte */
+		e |= (*p >> 4) & 0xF;
+		fhi = (*p & 0xF) << 24;
+		p += incr;
 
-	/* Third byte */
-	fhi |= *p << 16;
-	p += incr;
+		if (e == 2047) {
+			PyErr_SetString(
+				PyExc_ValueError,
+				"can't unpack IEEE 754 special value "
+				"on non-IEEE platform");
+			return -1.0;
+		}
 
-	/* Fourth byte */
-	fhi |= *p  << 8;
-	p += incr;
+		/* Third byte */
+		fhi |= *p << 16;
+		p += incr;
 
-	/* Fifth byte */
-	fhi |= *p;
-	p += incr;
+		/* Fourth byte */
+		fhi |= *p  << 8;
+		p += incr;
 
-	/* Sixth byte */
-	flo = *p << 16;
-	p += incr;
+		/* Fifth byte */
+		fhi |= *p;
+		p += incr;
 
-	/* Seventh byte */
-	flo |= *p << 8;
-	p += incr;
+		/* Sixth byte */
+		flo = *p << 16;
+		p += incr;
 
-	/* Eighth byte */
-	flo |= *p;
+		/* Seventh byte */
+		flo |= *p << 8;
+		p += incr;
 
-	x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
-	x /= 268435456.0; /* 2**28 */
+		/* Eighth byte */
+		flo |= *p;
 
-	/* XXX This sadly ignores Inf/NaN */
-	if (e == 0)
-		e = -1022;
-	else {
-		x += 1.0;
-		e -= 1023;
-	}
-	x = ldexp(x, e);
+		x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
+		x /= 268435456.0; /* 2**28 */
 
-	if (sign)
-		x = -x;
+		if (e == 0)
+			e = -1022;
+		else {
+			x += 1.0;
+			e -= 1023;
+		}
+		x = ldexp(x, e);
 
-	return x;
+		if (sign)
+			x = -x;
+
+		return x;
+	}
+	else {
+		if ((double_format == ieee_little_endian_format && !le)
+		    || (double_format == ieee_big_endian_format && le)) {
+			char buf[8];
+			char *d = &buf[7];
+			int i;
+			
+			for (i = 0; i < 8; i++) {
+				*d-- = *p++;
+			}
+			return *(double*)&buf[0];
+		}
+		else {
+			return *(double*)p;
+		}
+	}
 }

Index: funcobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v
retrieving revision 2.55.2.4
retrieving revision 2.55.2.5
diff -u -d -r2.55.2.4 -r2.55.2.5
--- funcobject.c	14 Oct 2005 20:09:47 -0000	2.55.2.4
+++ funcobject.c	16 Oct 2005 05:24:04 -0000	2.55.2.5
@@ -264,8 +264,6 @@
 static PyObject *
 func_get_name(PyFunctionObject *op)
 {
-	if (restricted())
-		return NULL;
 	Py_INCREF(op->func_name);
 	return op->func_name;
 }

Index: genobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/genobject.c,v
retrieving revision 1.4.4.1
retrieving revision 1.4.4.2
diff -u -d -r1.4.4.1 -r1.4.4.2
--- genobject.c	7 Jan 2005 07:04:02 -0000	1.4.4.1
+++ genobject.c	16 Oct 2005 05:24:04 -0000	1.4.4.2
@@ -15,15 +15,31 @@
 static void
 gen_dealloc(PyGenObject *gen)
 {
+	PyObject *self = (PyObject *) gen;
+
 	_PyObject_GC_UNTRACK(gen);
+
 	if (gen->gi_weakreflist != NULL)
 		PyObject_ClearWeakRefs((PyObject *) gen);
-	Py_DECREF(gen->gi_frame);
+
+
+	_PyObject_GC_TRACK(self);
+
+	if (gen->gi_frame->f_stacktop!=NULL) {
+		/* Generator is paused, so we need to close */
+		gen->ob_type->tp_del(self);
+		if (self->ob_refcnt > 0)
+			return;		/* resurrected.  :( */
+	}
+
+	_PyObject_GC_UNTRACK(self);
+	Py_XDECREF(gen->gi_frame);
 	PyObject_GC_Del(gen);
 }
 
+
 static PyObject *
-gen_iternext(PyGenObject *gen)
+gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
 {
 	PyThreadState *tstate = PyThreadState_GET();
 	PyFrameObject *f = gen->gi_frame;
@@ -34,8 +50,24 @@
 				"generator already executing");
 		return NULL;
 	}
-	if (f->f_stacktop == NULL)
+	if ((PyObject *)f == Py_None || f->f_stacktop == NULL) {
+		/* Only set exception if called from send() */
+		if (arg && !exc) PyErr_SetNone(PyExc_StopIteration);
 		return NULL;
+	}
+
+	if (f->f_lasti == -1) {
+		if (arg && arg != Py_None) {
+			PyErr_SetString(PyExc_TypeError,
+				"can't send non-None value to a just-started generator");
+			return NULL;
+		}
+	} else {
+		/* Push arg onto the frame's value stack */
+		result = arg ? arg : Py_None;
+	        Py_INCREF(result);
+	        *(f->f_stacktop++) = result;
+	}
 
 	/* Generators always return to their most recent caller, not
 	 * necessarily their creator. */
@@ -44,13 +76,13 @@
 	f->f_back = tstate->frame;
 
 	gen->gi_running = 1;
-	result = PyEval_EvalFrame(f);
+	result = PyEval_EvalFrameEx(f, exc);
 	gen->gi_running = 0;
 
 	/* Don't keep the reference to f_back any longer than necessary.  It
 	 * may keep a chain of frames alive or it could create a reference
 	 * cycle. */
-	assert(f->f_back != NULL);
+	assert(f->f_back == tstate->frame);
 	Py_CLEAR(f->f_back);
 
 	/* If the generator just returned (as opposed to yielding), signal
@@ -58,17 +90,199 @@
 	if (result == Py_None && f->f_stacktop == NULL) {
 		Py_DECREF(result);
 		result = NULL;
+		/* Set exception if not called by gen_iternext() */
+		if (arg) PyErr_SetNone(PyExc_StopIteration);
+	}
+
+	if (!result || f->f_stacktop == NULL) {
+		/* generator can't be rerun, so release the frame */
+		Py_DECREF(f);
+		gen->gi_frame = (PyFrameObject *)Py_None;
+		Py_INCREF(Py_None);
 	}
 
 	return result;
 }
 
+PyDoc_STRVAR(send_doc,
+"send(arg) -> send 'arg' into generator, return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_send(PyGenObject *gen, PyObject *arg)
+{
+	return gen_send_ex(gen, arg, 0);
+}
+
+PyDoc_STRVAR(close_doc,
+"close(arg) -> raise GeneratorExit inside generator.");
+
+static PyObject *
+gen_close(PyGenObject *gen, PyObject *args)
+{
+	PyObject *retval;
+	PyErr_SetNone(PyExc_GeneratorExit);
+	retval = gen_send_ex(gen, Py_None, 1);
+	if (retval) {
+		Py_DECREF(retval);
+		PyErr_SetString(PyExc_RuntimeError,
+			"generator ignored GeneratorExit");
+		return NULL;
+	}
+	if ( PyErr_ExceptionMatches(PyExc_StopIteration) 
+	     || PyErr_ExceptionMatches(PyExc_GeneratorExit) ) 
+	{
+		PyErr_Clear();	/* ignore these errors */
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return NULL;
+}
+
+static void
+gen_del(PyObject *self)
+{
+        PyObject *res;
+        PyObject *error_type, *error_value, *error_traceback;
+	PyGenObject *gen = (PyGenObject *)self;
+
+	if ((PyObject *)gen->gi_frame == Py_None || gen->gi_frame->f_stacktop==NULL)
+		/* Generator isn't paused, so no need to close */
+		return;
+
+        /* Temporarily resurrect the object. */
+        assert(self->ob_refcnt == 0);
+        self->ob_refcnt = 1;
+
+        /* Save the current exception, if any. */
+        PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+	res = gen_close((PyGenObject *)self, NULL);
+
+	if (res == NULL)
+		PyErr_WriteUnraisable((PyObject *)self);
+	else
+		Py_DECREF(res);
+
+        /* Restore the saved exception. */
+        PyErr_Restore(error_type, error_value, error_traceback);
+
+        /* Undo the temporary resurrection; can't use DECREF here, it would
+         * cause a recursive call.
+         */
+        assert(self->ob_refcnt > 0);
+        if (--self->ob_refcnt == 0)
+                return; /* this is the normal path out */
+
+        /* close() resurrected it!  Make it look like the original Py_DECREF
+         * never happened.
+         */
+        {
+                int refcnt = self->ob_refcnt;
+                _Py_NewReference(self);
+                self->ob_refcnt = refcnt;
+        }
+        assert(!PyType_IS_GC(self->ob_type) ||
+               _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+
+        /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+         * we need to undo that. */
+        _Py_DEC_REFTOTAL;
+        /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+         * chain, so no more to do there.
+         * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+         * _Py_NewReference bumped tp_allocs:  both of those need to be
+         * undone.
+         */
+#ifdef COUNT_ALLOCS
+        --self->ob_type->tp_frees;
+        --self->ob_type->tp_allocs;
+#endif
+}
+
+
+
+PyDoc_STRVAR(throw_doc,
+"throw(typ[,val[,tb]]) -> raise exception in generator, return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_throw(PyGenObject *gen, PyObject *args) 
+{
+	PyObject *typ;
+	PyObject *tb = NULL;
+	PyObject *val = NULL;
+
+	if (!PyArg_ParseTuple(args, "O|OO:throw", &typ, &val, &tb))
+		return NULL;
+
+	if (tb && !PyTraceBack_Check(tb)) {
+		PyErr_SetString(PyExc_TypeError,
+			"throw() third argument must be a traceback object");
+		return NULL;
+	}
+
+	Py_INCREF(typ);
+	Py_XINCREF(val);
+	Py_XINCREF(tb);
+
+	if (PyClass_Check(typ)) {
+		PyErr_NormalizeException(&typ, &val, &tb);
+	}
+
+	else if (PyInstance_Check(typ)) {
+		/* Raising an instance.  The value should be a dummy. */
+		if (val && val != Py_None) {
+			PyErr_SetString(PyExc_TypeError,
+			  "instance exception may not have a separate value");
+			goto failed_throw;
+		}
+		else {
+			/* Normalize to raise <class>, <instance> */
+			val = typ;
+			typ = (PyObject*) ((PyInstanceObject*)typ)->in_class;
+			Py_INCREF(typ);
+		}
+	}
+	else {
+		/* Not something you can raise.  You get an exception
+		   anyway, just not what you specified :-) */
+		PyErr_Format(PyExc_TypeError,
+			     "exceptions must be classes, or instances, not %s",
+			     typ->ob_type->tp_name);
+			goto failed_throw;
+	}
+
+	PyErr_Restore(typ,val,tb);
+	return gen_send_ex(gen, Py_None, 1);
+
+failed_throw:
+	/* Didn't use our arguments, so restore their original refcounts */
+	Py_DECREF(typ);
+	Py_XDECREF(val);
+	Py_XDECREF(tb);
+	return NULL;
+}
+
+
+static PyObject *
+gen_iternext(PyGenObject *gen)
+{
+	return gen_send_ex(gen, NULL, 0);
+}
+
+
 static PyMemberDef gen_memberlist[] = {
 	{"gi_frame",	T_OBJECT, offsetof(PyGenObject, gi_frame),	RO},
 	{"gi_running",	T_INT,    offsetof(PyGenObject, gi_running),	RO},
 	{NULL}	/* Sentinel */
 };
 
+static PyMethodDef gen_methods[] = {
+	{"send",(PyCFunction)gen_send, METH_O, send_doc},
+	{"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
+	{"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
+	{NULL, NULL}	/* Sentinel */
+};
+
 PyTypeObject PyGen_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,					/* ob_size */
@@ -99,11 +313,26 @@
 	offsetof(PyGenObject, gi_weakreflist),	/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)gen_iternext,		/* tp_iternext */
-	0,					/* tp_methods */
+	gen_methods,				/* tp_methods */
 	gen_memberlist,				/* tp_members */
 	0,					/* tp_getset */
 	0,					/* tp_base */
 	0,					/* tp_dict */
+        
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+	0,					/* tp_free */
+	0,					/* tp_is_gc */
+	0,					/* tp_bases */
+	0,					/* tp_mro */
+	0,					/* tp_cache */
+	0,					/* tp_subclasses */
+	0,					/* tp_weaklist */
+	gen_del,				/* tp_del */
 };
 
 PyObject *

Index: intobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v
retrieving revision 2.84.2.2
retrieving revision 2.84.2.3
diff -u -d -r2.84.2.2 -r2.84.2.3
--- intobject.c	7 Jan 2005 07:04:02 -0000	2.84.2.2
+++ intobject.c	16 Oct 2005 05:24:04 -0000	2.84.2.3
@@ -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: iterobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v
retrieving revision 1.10.2.2
retrieving revision 1.10.2.3
diff -u -d -r1.10.2.2 -r1.10.2.3
--- iterobject.c	7 Jan 2005 07:04:02 -0000	1.10.2.2
+++ iterobject.c	16 Oct 2005 05:24:04 -0000	1.10.2.3
@@ -71,7 +71,7 @@
 	return NULL;
 }
 
-static int
+static PyObject *
 iter_len(seqiterobject *it)
 {
 	int seqsize, len;
@@ -79,17 +79,19 @@
 	if (it->it_seq) {
 		seqsize = PySequence_Size(it->it_seq);
 		if (seqsize == -1)
-			return -1;
+			return NULL;
 		len = seqsize - it->it_index;
 		if (len >= 0)
-			return len;
+			return PyInt_FromLong(len);
 	}
-	return 0;
+	return PyInt_FromLong(0);
 }
 
-static PySequenceMethods iter_as_sequence = {
-	(inquiry)iter_len,		/* sq_length */
-	0,				/* sq_concat */
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef seqiter_methods[] = {
+	{"_length_cue", (PyCFunction)iter_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
 };
 
 PyTypeObject PySeqIter_Type = {
@@ -106,7 +108,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&iter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -122,13 +124,8 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)iter_iternext,		/* tp_iternext */
-	0,					/* tp_methods */
+	seqiter_methods,			/* tp_methods */
 	0,					/* tp_members */
-	0,					/* tp_getset */
-	0,					/* tp_base */
-	0,					/* tp_dict */
-	0,					/* tp_descr_get */
-	0,					/* tp_descr_set */
 };
 
 /* -------------------------------------- */
@@ -236,10 +233,4 @@
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)calliter_iternext,	/* tp_iternext */
 	0,					/* tp_methods */
-	0,					/* tp_members */
-	0,					/* tp_getset */
-	0,					/* tp_base */
-	0,					/* tp_dict */
-	0,					/* tp_descr_get */
-	0,					/* tp_descr_set */
 };

Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.114.2.2
retrieving revision 2.114.2.3
diff -u -d -r2.114.2.2 -r2.114.2.3
--- listobject.c	7 Jan 2005 07:04:02 -0000	2.114.2.2
+++ listobject.c	16 Oct 2005 05:24:04 -0000	2.114.2.3
@@ -775,8 +775,13 @@
 	iternext = *it->ob_type->tp_iternext;
 
 	/* Guess a result list size. */
-	n = PyObject_Size(b);
+	n = _PyObject_LengthCue(b);
 	if (n < 0) {
+		if (!PyErr_ExceptionMatches(PyExc_TypeError)  &&
+		    !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+			Py_DECREF(it);
+			return NULL;
+		}
 		PyErr_Clear();
 		n = 8;	/* arbitrary */
 	}
@@ -2759,21 +2764,23 @@
 	return NULL;
 }
 
-static int
+static PyObject *
 listiter_len(listiterobject *it)
 {
 	int len;
 	if (it->it_seq) {
 		len = PyList_GET_SIZE(it->it_seq) - it->it_index;
 		if (len >= 0)
-			return len;
+			return PyInt_FromLong((long)len);
 	}
-	return 0;
+	return PyInt_FromLong(0);
 }
 
-static PySequenceMethods listiter_as_sequence = {
-	(inquiry)listiter_len,		/* sq_length */
-	0,				/* sq_concat */
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef listiter_methods[] = {
+	{"_length_cue", (PyCFunction)listiter_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
 };
 
 PyTypeObject PyListIter_Type = {
@@ -2790,7 +2797,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&listiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -2806,13 +2813,8 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)listiter_next,		/* tp_iternext */
-	0,					/* tp_methods */
+	listiter_methods,			/* tp_methods */
 	0,					/* tp_members */
-	0,					/* tp_getset */
-	0,					/* tp_base */
-	0,					/* tp_dict */
-	0,					/* tp_descr_get */
-	0,					/* tp_descr_set */
 };
 
 /*********************** List Reverse Iterator **************************/

Index: listsort.txt
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listsort.txt,v
retrieving revision 1.6.10.1
retrieving revision 1.6.10.2
diff -u -d -r1.6.10.1 -r1.6.10.2
--- listsort.txt	28 Apr 2003 17:18:16 -0000	1.6.10.1
+++ listsort.txt	16 Oct 2005 05:24:04 -0000	1.6.10.2
@@ -54,6 +54,16 @@
 + Here are exact comparison counts across all the tests in sortperf.py,
   when run with arguments "15 20 1".
 
+  Column Key:
+      *sort: random data
+      \sort: descending data
+      /sort: ascending data
+      3sort: ascending, then 3 random exchanges
+      +sort: ascending, then 10 random at the end
+      ~sort: many duplicates
+      =sort: all equal
+      !sort: worst case scenario
+
   First the trivial cases, trivial for samplesort because it special-cased
   them, and trivial for timsort because it naturally works on runs.  Within
   an "n" block, the first line gives the # of compares done by samplesort,

Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.118.2.2
retrieving revision 1.118.2.3
diff -u -d -r1.118.2.2 -r1.118.2.3
--- longobject.c	7 Jan 2005 07:04:03 -0000	1.118.2.2
+++ longobject.c	16 Oct 2005 05:24:04 -0000	1.118.2.3
@@ -783,9 +783,30 @@
 		return -1;
 	}
 	if (!PyLong_Check(vv)) {
+		PyNumberMethods *nb;
+		PyObject *io;
 		if (PyInt_Check(vv))
 			return (PY_LONG_LONG)PyInt_AsLong(vv);
-		PyErr_BadInternalCall();
+		if ((nb = vv->ob_type->tp_as_number) == NULL ||
+		    nb->nb_int == NULL) {
+			PyErr_SetString(PyExc_TypeError, "an integer is required");
+			return -1;
+		}
+		io = (*nb->nb_int) (vv);
+		if (io == NULL)
+			return -1;
+		if (PyInt_Check(io)) {
+			bytes = PyInt_AsLong(io);
+			Py_DECREF(io);
+			return bytes;
+		}
+		if (PyLong_Check(io)) {
+			bytes = PyLong_AsLongLong(io);
+			Py_DECREF(io);
+			return bytes;
+		}
+		Py_DECREF(io);
+		PyErr_SetString(PyExc_TypeError, "integer conversion failed");
 		return -1;
 	}
 
@@ -1069,7 +1090,7 @@
 			assert(accumbits >= basebits);
 			do {
 				char cdigit = (char)(accum & (base - 1));
-				cdigit += (cdigit < 10) ? '0' : 'A'-10;
+				cdigit += (cdigit < 10) ? '0' : 'a'-10;
 				assert(p > PyString_AS_STRING(str));
 				*--p = cdigit;
 				accumbits -= basebits;
@@ -1123,7 +1144,7 @@
 				digit nextrem = (digit)(rem / base);
 				char c = (char)(rem - nextrem * base);
 				assert(p > PyString_AS_STRING(str));
-				c += (c < 10) ? '0' : 'A'-10;
+				c += (c < 10) ? '0' : 'a'-10;
 				*--p = c;
 				rem = nextrem;
 				--ntostore;
@@ -2339,8 +2360,11 @@
 		c = (PyLongObject *)x;
 		Py_INCREF(x);
 	}
-	else if (PyInt_Check(x))
+	else if (PyInt_Check(x)) {
 		c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x));
+		if (c == NULL)
+			goto Error;
+	}
 	else if (x == Py_None)
 		c = NULL;
 	else {
@@ -2490,14 +2514,14 @@
  	}
 	/* fall through */
  Done:
-	Py_XDECREF(a);
-	Py_XDECREF(b);
-	Py_XDECREF(c);
-	Py_XDECREF(temp);
 	if (b->ob_size > FIVEARY_CUTOFF) {
 		for (i = 0; i < 32; ++i)
 			Py_XDECREF(table[i]);
 	}
+	Py_DECREF(a);
+	Py_DECREF(b);
+	Py_XDECREF(c);
+	Py_XDECREF(temp);
 	return (PyObject *)z;
 }
 
@@ -2840,7 +2864,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.179.2.3
retrieving revision 2.179.2.4
diff -u -d -r2.179.2.3 -r2.179.2.4
--- object.c	7 Jan 2005 07:04:04 -0000	2.179.2.3
+++ object.c	16 Oct 2005 05:24:04 -0000	2.179.2.4
@@ -331,22 +331,48 @@
 }
 
 PyObject *
-PyObject_Str(PyObject *v)
+_PyObject_Str(PyObject *v)
 {
 	PyObject *res;
-
+	int type_ok;
 	if (v == NULL)
 		return PyString_FromString("<NULL>");
 	if (PyString_CheckExact(v)) {
 		Py_INCREF(v);
 		return v;
 	}
+#ifdef Py_USING_UNICODE
+	if (PyUnicode_CheckExact(v)) {
+		Py_INCREF(v);
+		return v;
+	}
+#endif
 	if (v->ob_type->tp_str == NULL)
 		return PyObject_Repr(v);
 
 	res = (*v->ob_type->tp_str)(v);
 	if (res == NULL)
 		return NULL;
+	type_ok = PyString_Check(res);
+#ifdef Py_USING_UNICODE
+	type_ok = type_ok || PyUnicode_Check(res);
+#endif
+	if (!type_ok) {
+		PyErr_Format(PyExc_TypeError,
+			     "__str__ returned non-string (type %.200s)",
+			     res->ob_type->tp_name);
+		Py_DECREF(res);
+		return NULL;
+	}
+	return res;
+}
+
+PyObject *
+PyObject_Str(PyObject *v)
+{
+	PyObject *res = _PyObject_Str(v);
+	if (res == NULL)
+		return NULL;
 #ifdef Py_USING_UNICODE
 	if (PyUnicode_Check(res)) {
 		PyObject* str;
@@ -358,13 +384,7 @@
 		    	return NULL;
 	}
 #endif
-	if (!PyString_Check(res)) {
-		PyErr_Format(PyExc_TypeError,
-			     "__str__ returned non-string (type %.200s)",
-			     res->ob_type->tp_name);
-		Py_DECREF(res);
-		return NULL;
-	}
+	assert(PyString_Check(res));
 	return res;
 }
 
@@ -373,6 +393,8 @@
 PyObject_Unicode(PyObject *v)
 {
 	PyObject *res;
+	PyObject *func;
+	static PyObject *unicodestr;
 
 	if (v == NULL)
 		res = PyString_FromString("<NULL>");
@@ -380,35 +402,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 +443,7 @@
 		if (str)
 			res = str;
 		else
-		    	return NULL;
+			return NULL;
 	}
 	return res;
 }

Index: obmalloc.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/obmalloc.c,v
retrieving revision 2.45.2.2
retrieving revision 2.45.2.3
diff -u -d -r2.45.2.2 -r2.45.2.3
--- obmalloc.c	7 Jan 2005 07:04:04 -0000	2.45.2.2
+++ obmalloc.c	16 Oct 2005 05:24:04 -0000	2.45.2.3
@@ -139,9 +139,9 @@
  * getpagesize() call or deduced from various header files. To make
  * things simpler, we assume that it is 4K, which is OK for most systems.
  * It is probably better if this is the native page size, but it doesn't
- * have to be.  In theory, if SYSTEM_PAGE_SIZE is larger than the native page 
- * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation 
- * violation fault.  4K is apparently OK for all the platforms that python 
+ * have to be.  In theory, if SYSTEM_PAGE_SIZE is larger than the native page
+ * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation
+ * violation fault.  4K is apparently OK for all the platforms that python
  * currently targets.
  */
 #define SYSTEM_PAGE_SIZE	(4 * 1024)
@@ -841,30 +841,26 @@
 		}
 		return bp;
 	}
-	/* We're not managing this block. */
-	if (nbytes <= SMALL_REQUEST_THRESHOLD) {
-		/* Take over this block -- ask for at least one byte so
-		 * we really do take it over (PyObject_Malloc(0) goes to
-		 * the system malloc).
-		 */
-		bp = PyObject_Malloc(nbytes ? nbytes : 1);
-		if (bp != NULL) {
-			memcpy(bp, p, nbytes);
-			free(p);
-		}
-		else if (nbytes == 0) {
-			/* Meet the doc's promise that nbytes==0 will
-			 * never return a NULL pointer when p isn't NULL.
-			 */
-			bp = p;
-		}
-
-	}
-	else {
-		assert(nbytes != 0);
-		bp = realloc(p, nbytes);
-	}
-	return bp;
+	/* We're not managing this block.  If nbytes <=
+	 * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this
+	 * block.  However, if we do, we need to copy the valid data from
+	 * the C-managed block to one of our blocks, and there's no portable
+	 * way to know how much of the memory space starting at p is valid.
+	 * As bug 1185883 pointed out the hard way, it's possible that the
+	 * C-managed block is "at the end" of allocated VM space, so that
+	 * a memory fault can occur if we try to copy nbytes bytes starting
+	 * at p.  Instead we punt:  let C continue to manage this block.
+         */
+	if (nbytes)
+		return realloc(p, nbytes);
+	/* C doesn't define the result of realloc(p, 0) (it may or may not
+	 * return NULL then), but Python's docs promise that nbytes==0 never
+	 * returns NULL.  We don't pass 0 to realloc(), to avoid that endcase
+	 * to begin with.  Even then, we can't be sure that realloc() won't
+	 * return NULL.
+	 */
+	bp = realloc(p, 1);
+   	return bp ? bp : p;
 }
 
 #else	/* ! WITH_PYMALLOC */

Index: rangeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v
retrieving revision 2.41.2.2
retrieving revision 2.41.2.3
diff -u -d -r2.41.2.2 -r2.41.2.3
--- rangeobject.c	7 Jan 2005 07:04:04 -0000	2.41.2.2
+++ rangeobject.c	16 Oct 2005 05:24:04 -0000	2.41.2.3
@@ -45,6 +45,9 @@
 	long ilow = 0, ihigh = 0, istep = 1;
 	long n;
 
+	if (!_PyArg_NoKeywords("xrange()", kw))
+		return NULL;
+
 	if (PyTuple_Size(args) <= 1) {
 		if (!PyArg_ParseTuple(args,
 				"l;xrange() requires 1-3 int arguments",
@@ -259,17 +262,18 @@
 	return NULL;
 }
 
-static int
+static PyObject *
 rangeiter_len(rangeiterobject *r)
 {
-	return r->len - r->index;
+	return PyInt_FromLong(r->len - r->index);
 }
 
-static PySequenceMethods rangeiter_as_sequence = {
-	(inquiry)rangeiter_len,		/* sq_length */
-	0,				/* sq_concat */
-};
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
 
+static PyMethodDef rangeiter_methods[] = {
+	{"_length_cue", (PyCFunction)rangeiter_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
 
 static PyTypeObject Pyrangeiter_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
@@ -285,7 +289,7 @@
 	0,                                      /* tp_compare */
 	0,                                      /* tp_repr */
 	0,                                      /* tp_as_number */
-	&rangeiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,                                      /* tp_as_mapping */
 	0,                                      /* tp_hash */
 	0,                                      /* tp_call */
@@ -301,5 +305,6 @@
 	0,                                      /* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)rangeiter_next,		/* tp_iternext */
-	0,					/* tp_methods */
+	rangeiter_methods,			/* tp_methods */
+	0,
 };

Index: setobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/setobject.c,v
retrieving revision 1.31.4.1
retrieving revision 1.31.4.2
diff -u -d -r1.31.4.1 -r1.31.4.2
--- setobject.c	7 Jan 2005 07:04:04 -0000	1.31.4.1
+++ setobject.c	16 Oct 2005 05:24:04 -0000	1.31.4.2
@@ -1,41 +1,882 @@
-#include "Python.h"
-#include "structmember.h"
 
 /* set object implementation 
-   written and maintained by Raymond D. Hettinger <python at rcn.com>
-   derived from sets.py written by Greg V. Wilson, Alex Martelli, 
-   Guido van Rossum, Raymond Hettinger, and Tim Peters.
+   Written and maintained by Raymond D. Hettinger <python at rcn.com>
+   Derived from Lib/sets.py and Objects/dictobject.c.
 
-   Copyright (c) 2003 Python Software Foundation.
[...2120 lines suppressed...]
+
+	/* Verify constructors accept NULL arguments */
+	f = PySet_New(NULL);
+	assert(f != NULL);
+	assert(PySet_GET_SIZE(f) == 0);
+	Py_DECREF(f);
+	f = PyFrozenSet_New(NULL);
+	assert(f != NULL);
+	assert(PyFrozenSet_CheckExact(f));
+	assert(PySet_GET_SIZE(f) == 0);
+	Py_DECREF(f);
+
+	Py_DECREF(elem);
+	Py_DECREF(dup);
+	Py_RETURN_TRUE;
+}
+
+#undef assertRaises
+
+#endif

Index: sliceobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v
retrieving revision 2.15.2.2
retrieving revision 2.15.2.3
diff -u -d -r2.15.2.2 -r2.15.2.3
--- sliceobject.c	7 Jan 2005 07:04:05 -0000	2.15.2.2
+++ sliceobject.c	16 Oct 2005 05:24:04 -0000	2.15.2.3
@@ -174,6 +174,9 @@
 
 	start = stop = step = NULL;
 
+	if (!_PyArg_NoKeywords("slice()", kw))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step))
 		return NULL;
 

Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.168.2.2
retrieving revision 2.168.2.3
diff -u -d -r2.168.2.2 -r2.168.2.3
--- stringobject.c	7 Jan 2005 07:04:05 -0000	2.168.2.2
+++ stringobject.c	16 Oct 2005 05:24:04 -0000	2.168.2.3
@@ -52,6 +52,7 @@
 PyString_FromStringAndSize(const char *str, int size)
 {
 	register PyStringObject *op;
+	assert(size >= 0);
 	if (size == 0 && (op = nullstring) != NULL) {
 #ifdef COUNT_ALLOCS
 		null_strings++;
@@ -1001,8 +1002,12 @@
 static int
 string_contains(PyObject *a, PyObject *el)
 {
-	const char *lhs, *rhs, *end;
-	int size;
+	char *s = PyString_AS_STRING(a);
+	const char *sub = PyString_AS_STRING(el);
+	char *last;
+	int len_sub = PyString_GET_SIZE(el);
+	int shortsub;
+	char firstchar, lastchar;
 
 	if (!PyString_CheckExact(el)) {
 #ifdef Py_USING_UNICODE
@@ -1015,20 +1020,29 @@
 			return -1;
 		}
 	}
-	size = PyString_GET_SIZE(el);
-	rhs = PyString_AS_STRING(el);
-	lhs = PyString_AS_STRING(a);
-
-	/* optimize for a single character */
-	if (size == 1)
-		return memchr(lhs, *rhs, PyString_GET_SIZE(a)) != NULL;
 
-	end = lhs + (PyString_GET_SIZE(a) - size);
-	while (lhs <= end) {
-		if (memcmp(lhs++, rhs, size) == 0)
+	if (len_sub == 0)
+		return 1;
+	/* last points to one char beyond the start of the rightmost 
+	   substring.  When s<last, there is still room for a possible match
+	   and s[0] through s[len_sub-1] will be in bounds.
+	   shortsub is len_sub minus the last character which is checked
+	   separately just before the memcmp().  That check helps prevent
+	   false starts and saves the setup time for memcmp().
+	*/
+	firstchar = sub[0];
+	shortsub = len_sub - 1;
+	lastchar = sub[shortsub];
+	last = s + PyString_GET_SIZE(a) - len_sub + 1;
+	while (s < last) {
+		s = memchr(s, firstchar, last-s);
+		if (s == NULL)
+			return 0;
+		assert(s < last);
+		if (s[shortsub] == lastchar && memcmp(s, sub, shortsub) == 0)
 			return 1;
+		s++;
 	}
-
 	return 0;
 }
 
@@ -2131,7 +2145,7 @@
 static PyObject *
 string_count(PyStringObject *self, PyObject *args)
 {
-	const char *s = PyString_AS_STRING(self), *sub;
+	const char *s = PyString_AS_STRING(self), *sub, *t;
 	int len = PyString_GET_SIZE(self), n;
 	int i = 0, last = INT_MAX;
 	int m, r;
@@ -2172,11 +2186,16 @@
 		} else {
 			i++;
 		}
+		if (i >= m)
+			break;
+		t = memchr(s+i, sub[0], m-i);
+		if (t == NULL)
+			break;
+		i = t - s;
 	}
 	return PyInt_FromLong((long) r);
 }
 
-
 PyDoc_STRVAR(swapcase__doc__,
 "S.swapcase() -> string\n\
 \n\
@@ -3734,18 +3753,12 @@
 	}
 
 	/* Fix up case for hex conversions. */
-	switch (type) {
-	case 'x':
-		/* Need to convert all upper case letters to lower case. */
+	if (type == 'X') {
+		/* Need to convert all lower case letters to upper case.
+		   and need to convert 0x to 0X (and -0x to -0X). */
 		for (i = 0; i < len; i++)
-			if (buf[i] >= 'A' && buf[i] <= 'F')
-				buf[i] += 'a'-'A';
-		break;
-	case 'X':
-		/* Need to convert 0x to 0X (and -0x to -0X). */
-		if (buf[sign + 1] == 'x')
-			buf[sign + 1] = 'X';
-		break;
+			if (buf[i] >= 'a' && buf[i] <= 'x')
+				buf[i] -= 'a'-'A';
 	}
 	*pbuf = buf;
 	*plen = len;
@@ -3840,7 +3853,6 @@
 	return 1;
 }
 
-
 /* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
 
    FORMATBUFLEN is the length of the buffer in which the floats, ints, &
@@ -4072,18 +4084,22 @@
 					goto unicode;
 				}
 #endif
+				temp = _PyObject_Str(v);
+#ifdef Py_USING_UNICODE
+				if (temp != NULL && PyUnicode_Check(temp)) {
+					Py_DECREF(temp);
+					fmt = fmt_start;
+					argidx = argidx_start;
+					goto unicode;
+				}
+#endif
 				/* Fall through */
 			case 'r':
-				if (c == 's')
-					temp = PyObject_Str(v);
-				else
+				if (c == 'r')
 					temp = PyObject_Repr(v);
 				if (temp == NULL)
 					goto error;
 				if (!PyString_Check(temp)) {
-					/* XXX Note: this should never happen,
-					   since PyObject_Repr() and
-					   PyObject_Str() assure this */
 					PyErr_SetString(PyExc_TypeError,
 					  "%s argument has non-string str()");
 					Py_DECREF(temp);

Index: tupleobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v
retrieving revision 2.68.2.2
retrieving revision 2.68.2.3
diff -u -d -r2.68.2.2 -r2.68.2.3
--- tupleobject.c	7 Jan 2005 07:04:06 -0000	2.68.2.2
+++ tupleobject.c	16 Oct 2005 05:24:04 -0000	2.68.2.3
@@ -851,17 +851,20 @@
 	return NULL;
 }
 
-static int
+static PyObject *
 tupleiter_len(tupleiterobject *it)
 {
+	int len = 0;
 	if (it->it_seq)
-		return PyTuple_GET_SIZE(it->it_seq) - it->it_index;
-	return 0;
+		len = PyTuple_GET_SIZE(it->it_seq) - it->it_index;
+	return PyInt_FromLong(len);
 }
 
-static PySequenceMethods tupleiter_as_sequence = {
-	(inquiry)tupleiter_len,		/* sq_length */
-	0,				/* sq_concat */
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef tupleiter_methods[] = {
+	{"_length_cue", (PyCFunction)tupleiter_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
 };
 
 PyTypeObject PyTupleIter_Type = {
@@ -878,7 +881,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&tupleiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -894,4 +897,6 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)tupleiter_next,		/* tp_iternext */
+	tupleiter_methods,			/* tp_methods */
+	0,
 };

Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.157.2.3
retrieving revision 2.157.2.4
diff -u -d -r2.157.2.3 -r2.157.2.4
--- typeobject.c	7 Jan 2005 07:04:06 -0000	2.157.2.3
+++ typeobject.c	16 Oct 2005 05:24:04 -0000	2.157.2.4
@@ -2516,7 +2516,7 @@
 
 	clsdict = ((PyTypeObject *)cls)->tp_dict;
 	slotnames = PyDict_GetItemString(clsdict, "__slotnames__");
-	if (slotnames != NULL) {
+	if (slotnames != NULL && PyList_Check(slotnames)) {
 		Py_INCREF(slotnames);
 		return slotnames;
 	}
@@ -4065,14 +4065,24 @@
 {
 	static PyObject *len_str;
 	PyObject *res = call_method(self, "__len__", &len_str, "()");
+	long temp;
 	int len;
 
 	if (res == NULL)
 		return -1;
-	len = (int)PyInt_AsLong(res);
+	temp = PyInt_AsLong(res);
+	len = (int)temp;
 	Py_DECREF(res);
 	if (len == -1 && PyErr_Occurred())
 		return -1;
+#if SIZEOF_INT < SIZEOF_LONG
+	/* Overflow check -- range of PyInt is more than C int */
+	if (len != temp) {
+		PyErr_SetString(PyExc_OverflowError,
+			"__len__() should return 0 <= outcome < 2**31");
+		return -1;
+	}
+#endif
 	if (len < 0) {
 		PyErr_SetString(PyExc_ValueError,
 				"__len__() should return >= 0");
@@ -4747,6 +4757,12 @@
 	Py_DECREF(meth);
 	if (res == NULL)
 		return -1;
+	if (res != Py_None) {
+		PyErr_SetString(PyExc_TypeError,
+			   "__init__() should return None");
+		Py_DECREF(res);
+		return -1;
+	}
 	Py_DECREF(res);
 	return 0;
 }
@@ -4896,6 +4912,12 @@
 #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
 	ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
 	       "x." NAME "(y) <==> y" DOC "x")
+#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
+	       "x." NAME "(y) <==> " DOC)
+#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+	ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
+	       "x." NAME "(y) <==> " DOC)
 
 static slotdef slotdefs[] = {
 	SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry,
@@ -4964,9 +4986,9 @@
 		"%"),
 	RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
 		 "%"),
-	BINSLOT("__divmod__", nb_divmod, slot_nb_divmod,
+	BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod,
 		"divmod(x, y)"),
-	RBINSLOT("__rdivmod__", nb_divmod, slot_nb_divmod,
+	RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod,
 		 "divmod(y, x)"),
 	NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
 	       "x.__pow__(y[, z]) <==> pow(x, y[, z])"),
@@ -5636,7 +5658,7 @@
 		return self;
 	}
 	if (su->ob_type != &PySuper_Type)
-		/* If su is not an instance of a subclass of super,
+		/* If su is an instance of a (strict) subclass of super,
 		   call its type */
 		return PyObject_CallFunction((PyObject *)su->ob_type,
 					     "OO", su->type, obj);

Index: unicodeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v
retrieving revision 2.155.2.2
retrieving revision 2.155.2.3
diff -u -d -r2.155.2.2 -r2.155.2.3
--- unicodeobject.c	7 Jan 2005 07:04:09 -0000	2.155.2.2
+++ unicodeobject.c	16 Oct 2005 05:24:04 -0000	2.155.2.3
@@ -2273,6 +2273,81 @@
 					    PyUnicode_GET_SIZE(unicode));
 }
 
+/* --- Unicode Internal Codec ------------------------------------------- */
+
+PyObject *_PyUnicode_DecodeUnicodeInternal(const char *s,
+					   int size,
+					   const char *errors)
+{
+    const char *starts = s;
+    int startinpos;
+    int endinpos;
+    int outpos;
+    Py_UNICODE unimax;
+    PyUnicodeObject *v;
+    Py_UNICODE *p;
+    const char *end;
+    const char *reason;
+    PyObject *errorHandler = NULL;
+    PyObject *exc = NULL;
+
+    unimax = PyUnicode_GetMax();
+    v = _PyUnicode_New((size+Py_UNICODE_SIZE-1)/ Py_UNICODE_SIZE);
+    if (v == NULL)
+	goto onError;
+    if (PyUnicode_GetSize((PyObject *)v) == 0)
+	return (PyObject *)v;
+    p = PyUnicode_AS_UNICODE(v);
+    end = s + size;
+
+    while (s < end) {
+        *p = *(Py_UNICODE *)s;
+        /* We have to sanity check the raw data, otherwise doom looms for
+           some malformed UCS-4 data. */
+        if (
+            #ifdef Py_UNICODE_WIDE
+            *p > unimax || *p < 0 ||
+            #endif
+            end-s < Py_UNICODE_SIZE
+            )
+            {
+            startinpos = s - starts;
+            if (end-s < Py_UNICODE_SIZE) {
+                endinpos = end-starts;
+                reason = "truncated input";
+            }
+            else {
+                endinpos = s - starts + Py_UNICODE_SIZE;
+                reason = "illegal code point (> 0x10FFFF)";
+            }
+            outpos = p - PyUnicode_AS_UNICODE(v);
+            if (unicode_decode_call_errorhandler(
+                    errors, &errorHandler,
+                    "unicode_internal", reason,
+                    starts, size, &startinpos, &endinpos, &exc, &s,
+                    (PyObject **)&v, &outpos, &p)) {
+                goto onError;
+            }
+        }
+        else {
+            p++;
+            s += Py_UNICODE_SIZE;
+        }
+    }
+
+    if (_PyUnicode_Resize(&v, (int)(p - PyUnicode_AS_UNICODE(v))) < 0)
+        goto onError;
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return (PyObject *)v;
+
+ onError:
+    Py_XDECREF(v);
+    Py_XDECREF(errorHandler);
+    Py_XDECREF(exc);
+    return NULL;
+}
+
 /* --- Latin-1 Codec ------------------------------------------------------ */
 
 PyObject *PyUnicode_DecodeLatin1(const char *s,
@@ -2758,6 +2833,8 @@
     int extrachars = 0;
     PyObject *errorHandler = NULL;
     PyObject *exc = NULL;
+    Py_UNICODE *mapstring = NULL;
+    int maplen = 0;
 
     /* Default to Latin-1 */
     if (mapping == NULL)
@@ -2770,91 +2847,121 @@
 	return (PyObject *)v;
     p = PyUnicode_AS_UNICODE(v);
     e = s + size;
-    while (s < e) {
-	unsigned char ch = *s;
-	PyObject *w, *x;
+    if (PyUnicode_CheckExact(mapping)) {
+	mapstring = PyUnicode_AS_UNICODE(mapping);
+	maplen = PyUnicode_GET_SIZE(mapping);
+	while (s < e) {
+	    unsigned char ch = *s;
+	    Py_UNICODE x = 0xfffe; /* illegal value */
 
-	/* Get mapping (char ordinal -> integer, Unicode char or None) */
-	w = PyInt_FromLong((long)ch);
-	if (w == NULL)
-	    goto onError;
-	x = PyObject_GetItem(mapping, w);
-	Py_DECREF(w);
-	if (x == NULL) {
-	    if (PyErr_ExceptionMatches(PyExc_LookupError)) {
-		/* No mapping found means: mapping is undefined. */
-		PyErr_Clear();
-		x = Py_None;
-		Py_INCREF(x);
-	    } else
-		goto onError;
-	}
+	    if (ch < maplen)
+		x = mapstring[ch];
 
-	/* Apply mapping */
-	if (PyInt_Check(x)) {
-	    long value = PyInt_AS_LONG(x);
-	    if (value < 0 || value > 65535) {
-		PyErr_SetString(PyExc_TypeError,
-				"character mapping must be in range(65536)");
-		Py_DECREF(x);
-		goto onError;
+	    if (x == 0xfffe) {
+		/* undefined mapping */
+		outpos = p-PyUnicode_AS_UNICODE(v);
+		startinpos = s-starts;
+		endinpos = startinpos+1;
+		if (unicode_decode_call_errorhandler(
+		     errors, &errorHandler,
+		     "charmap", "character maps to <undefined>",
+		     starts, size, &startinpos, &endinpos, &exc, &s,
+		     (PyObject **)&v, &outpos, &p)) {
+		    goto onError;
+		}
+		continue;
 	    }
-	    *p++ = (Py_UNICODE)value;
+	    *p++ = x;
+	    ++s;
 	}
-	else if (x == Py_None) {
-	    /* undefined mapping */
-	    outpos = p-PyUnicode_AS_UNICODE(v);
-	    startinpos = s-starts;
-	    endinpos = startinpos+1;
-	    if (unicode_decode_call_errorhandler(
-		 errors, &errorHandler,
-		 "charmap", "character maps to <undefined>",
-		 starts, size, &startinpos, &endinpos, &exc, &s,
-		 (PyObject **)&v, &outpos, &p)) {
-		Py_DECREF(x);
+    }
+    else {
+	while (s < e) {
+	    unsigned char ch = *s;
+	    PyObject *w, *x;
+
+	    /* Get mapping (char ordinal -> integer, Unicode char or None) */
+	    w = PyInt_FromLong((long)ch);
+	    if (w == NULL)
 		goto onError;
+	    x = PyObject_GetItem(mapping, w);
+	    Py_DECREF(w);
+	    if (x == NULL) {
+		if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+		    /* No mapping found means: mapping is undefined. */
+		    PyErr_Clear();
+		    x = Py_None;
+		    Py_INCREF(x);
+		} else
+		    goto onError;
 	    }
-	    continue;
-	}
-	else if (PyUnicode_Check(x)) {
-	    int targetsize = PyUnicode_GET_SIZE(x);
-
-	    if (targetsize == 1)
-		/* 1-1 mapping */
-		*p++ = *PyUnicode_AS_UNICODE(x);
-
-	    else if (targetsize > 1) {
-		/* 1-n mapping */
-		if (targetsize > extrachars) {
-		    /* resize first */
-		    int oldpos = (int)(p - PyUnicode_AS_UNICODE(v));
-		    int needed = (targetsize - extrachars) + \
-			         (targetsize << 2);
-		    extrachars += needed;
-		    if (_PyUnicode_Resize(&v,
-					 PyUnicode_GET_SIZE(v) + needed) < 0) {
-			Py_DECREF(x);
-			goto onError;
+    
+	    /* Apply mapping */
+	    if (PyInt_Check(x)) {
+		long value = PyInt_AS_LONG(x);
+		if (value < 0 || value > 65535) {
+		    PyErr_SetString(PyExc_TypeError,
+				    "character mapping must be in range(65536)");
+		    Py_DECREF(x);
+		    goto onError;
+		}
+		*p++ = (Py_UNICODE)value;
+	    }
+	    else if (x == Py_None) {
+		/* undefined mapping */
+		outpos = p-PyUnicode_AS_UNICODE(v);
+		startinpos = s-starts;
+		endinpos = startinpos+1;
+		if (unicode_decode_call_errorhandler(
+		     errors, &errorHandler,
+		     "charmap", "character maps to <undefined>",
+		     starts, size, &startinpos, &endinpos, &exc, &s,
+		     (PyObject **)&v, &outpos, &p)) {
+		    Py_DECREF(x);
+		    goto onError;
+		}
+		continue;
+	    }
+	    else if (PyUnicode_Check(x)) {
+		int targetsize = PyUnicode_GET_SIZE(x);
+    
+		if (targetsize == 1)
+		    /* 1-1 mapping */
+		    *p++ = *PyUnicode_AS_UNICODE(x);
+    
+		else if (targetsize > 1) {
+		    /* 1-n mapping */
+		    if (targetsize > extrachars) {
+			/* resize first */
+			int oldpos = (int)(p - PyUnicode_AS_UNICODE(v));
+			int needed = (targetsize - extrachars) + \
+				     (targetsize << 2);
+			extrachars += needed;
+			if (_PyUnicode_Resize(&v,
+					     PyUnicode_GET_SIZE(v) + needed) < 0) {
+			    Py_DECREF(x);
+			    goto onError;
+			}
+			p = PyUnicode_AS_UNICODE(v) + oldpos;
 		    }
-		    p = PyUnicode_AS_UNICODE(v) + oldpos;
+		    Py_UNICODE_COPY(p,
+				    PyUnicode_AS_UNICODE(x),
+				    targetsize);
+		    p += targetsize;
+		    extrachars -= targetsize;
 		}
-		Py_UNICODE_COPY(p,
-				PyUnicode_AS_UNICODE(x),
-				targetsize);
-		p += targetsize;
-		extrachars -= targetsize;
+		/* 1-0 mapping: skip the character */
+	    }
+	    else {
+		/* wrong return value */
+		PyErr_SetString(PyExc_TypeError,
+		      "character mapping must return integer, None or unicode");
+		Py_DECREF(x);
+		goto onError;
 	    }
-	    /* 1-0 mapping: skip the character */
-	}
-	else {
-	    /* wrong return value */
-	    PyErr_SetString(PyExc_TypeError,
-		  "character mapping must return integer, None or unicode");
 	    Py_DECREF(x);
-	    goto onError;
+	    ++s;
 	}
-	Py_DECREF(x);
-	++s;
     }
     if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v))
 	if (_PyUnicode_Resize(&v, (int)(p - PyUnicode_AS_UNICODE(v))) < 0)

Index: weakrefobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v
retrieving revision 1.9.2.2
retrieving revision 1.9.2.3
diff -u -d -r1.9.2.2 -r1.9.2.3
--- weakrefobject.c	7 Jan 2005 07:04:10 -0000	1.9.2.2
+++ weakrefobject.c	16 Oct 2005 05:24:05 -0000	1.9.2.3
@@ -505,11 +505,7 @@
     PyObject *o = PyWeakref_GET_OBJECT(proxy);
     if (!proxy_checkref(proxy))
         return -1;
-    if (o->ob_type->tp_as_number &&
-        o->ob_type->tp_as_number->nb_nonzero)
-        return (*o->ob_type->tp_as_number->nb_nonzero)(o);
-    else
-        return 1;
+    return PyObject_IsTrue(o);
 }
 
 static void



More information about the Python-checkins mailing list