Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r64002 | travis.oliphant | 2008-06-07 00:33:21 +0200 (Sat, 07 Jun 2008) | 1 line

  Add long double check support to configure test.
........
  r64003 | travis.oliphant | 2008-06-07 00:39:47 +0200 (Sat, 07 Jun 2008) | 1 line

  Remove locking part of new buffer protocol.
........
  r64012 | facundo.batista | 2008-06-07 15:36:36 +0200 (Sat, 07 Jun 2008) | 4 lines


  Finished bug #2451.  Fixed the retrying part to make it
  more robust.
........
  r64036 | georg.brandl | 2008-06-08 10:54:40 +0200 (Sun, 08 Jun 2008) | 2 lines

  #3028: tokenize passes the physical line.
........
  r64037 | georg.brandl | 2008-06-08 10:59:38 +0200 (Sun, 08 Jun 2008) | 2 lines

  Argh, I read it wrong. Reverted 64036 and added a clarifying remark.
........
  r64047 | raymond.hettinger | 2008-06-09 03:28:30 +0200 (Mon, 09 Jun 2008) | 1 line

  Issue3065:  Fixed pickling of named tuples.  Added tests.
........
  r64050 | raymond.hettinger | 2008-06-09 08:54:45 +0200 (Mon, 09 Jun 2008) | 1 line

  Issue #2138: Add math.factorial().
........
  r64051 | raymond.hettinger | 2008-06-09 10:33:37 +0200 (Mon, 09 Jun 2008) | 1 line

  Let set.union() and set.update() accept multiple inputs.
........
  r64052 | raymond.hettinger | 2008-06-09 11:29:17 +0200 (Mon, 09 Jun 2008) | 1 line

  Address double-rounding scenarios by setting all variables to long doubles.
........
  r64054 | raymond.hettinger | 2008-06-09 13:24:47 +0200 (Mon, 09 Jun 2008) | 1 line

  Unhappy buildbots.  Revert 64052.  Long doubles have unexpected effects on some builds.
........
  r64055 | raymond.hettinger | 2008-06-09 15:07:27 +0200 (Mon, 09 Jun 2008) | 1 line

  Let set.intersection() and set.intersection_update() take multiple input arguments.
........
  r64066 | robert.schuppenies | 2008-06-10 12:10:31 +0200 (Tue, 10 Jun 2008) | 2 lines

  Issue 3048: Fixed sys.getsizeof for unicode objects.
........
  r64071 | thomas.heller | 2008-06-10 16:07:12 +0200 (Tue, 10 Jun 2008) | 3 lines

  NEWS entry for:
  Add an optional 'offset' parameter to byref, defaulting to zero.
........
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 16c829a..f759ada 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -568,6 +568,54 @@
 Assumes IEEE-754 floating point arithmetic.");
 
 static PyObject *
+math_factorial(PyObject *self, PyObject *arg)
+{
+	long i, x;
+	PyObject *result, *iobj, *newresult;
+
+	if (PyFloat_Check(arg)) {
+		double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg);
+		if (dx != floor(dx)) {
+			PyErr_SetString(PyExc_ValueError, 
+				"factorial() only accepts integral values");
+			return NULL;
+		}
+	}
+
+	x = PyLong_AsLong(arg);
+	if (x == -1 && PyErr_Occurred())
+		return NULL;
+	if (x < 0) {
+		PyErr_SetString(PyExc_ValueError, 
+			"factorial() not defined for negative values");
+		return NULL;
+	}
+
+	result = (PyObject *)PyLong_FromLong(1);
+	if (result == NULL)
+		return NULL;
+	for (i=1 ; i<=x ; i++) {
+		iobj = (PyObject *)PyLong_FromLong(i);
+		if (iobj == NULL)
+			goto error;
+		newresult = PyNumber_Multiply(result, iobj);
+		Py_DECREF(iobj);
+		if (newresult == NULL)
+			goto error;
+		Py_DECREF(result);
+		result = newresult;
+	}
+	return result;
+
+error:
+	Py_DECREF(result);
+	Py_XDECREF(iobj);
+	return NULL;
+}
+
+PyDoc_STRVAR(math_factorial_doc, "Return n!");
+
+static PyObject *
 math_trunc(PyObject *self, PyObject *number)
 {
 	static PyObject *trunc_str = NULL;
@@ -1022,6 +1070,7 @@
 	{"degrees",	math_degrees,	METH_O,		math_degrees_doc},
 	{"exp",		math_exp,	METH_O,		math_exp_doc},
 	{"fabs",	math_fabs,	METH_O,		math_fabs_doc},
+	{"factorial",	math_factorial,	METH_O,		math_factorial_doc},
 	{"floor",	math_floor,	METH_O,		math_floor_doc},
 	{"fmod",	math_fmod,	METH_VARARGS,	math_fmod_doc},
 	{"frexp",	math_frexp,	METH_O,		math_frexp_doc},