Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361,
r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new
documentation. The only significant difference is that round(x) returns a float
to preserve backward-compatibility. See http://bugs.python.org/issue1689.
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 6996936..a7d77de 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1926,39 +1926,31 @@
 static PyObject *
 builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
 {
-	double number;
-	double f;
-	int ndigits = 0;
-	int i;
+#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */
+	int ndigits = UNDEF_NDIGITS;
 	static char *kwlist[] = {"number", "ndigits", 0};
+	PyObject *number;
 
-	if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round",
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:round",
                 kwlist, &number, &ndigits))
                 return NULL;
-	f = 1.0;
-	i = abs(ndigits);
-	while  (--i >= 0)
-		f = f*10.0;
-	if (ndigits < 0)
-		number /= f;
-	else
-		number *= f;
-	if (number >= 0.0)
-		number = floor(number + 0.5);
-	else
-		number = ceil(number - 0.5);
-	if (ndigits < 0)
-		number *= f;
-	else
-		number /= f;
-	return PyFloat_FromDouble(number);
+
+        // The py3k branch gets better errors for this by using
+        // _PyType_Lookup(), but since float's mro isn't set in py2.6,
+        // we just use PyObject_CallMethod here.
+        if (ndigits == UNDEF_NDIGITS)
+                return PyObject_CallMethod(number, "__round__", "");
+        else
+                return PyObject_CallMethod(number, "__round__", "i", ndigits);
+#undef UNDEF_NDIGITS
 }
 
 PyDoc_STRVAR(round_doc,
 "round(number[, ndigits]) -> floating point number\n\
 \n\
 Round a number to a given precision in decimal digits (default 0 digits).\n\
-This always returns a floating point number.  Precision may be negative.");
+This returns an int when called with one argument, otherwise a float.\n\
+Precision may be negative.");
 
 static PyObject *
 builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)
@@ -2039,6 +2031,20 @@
 Without arguments, equivalent to locals().\n\
 With an argument, equivalent to object.__dict__.");
 
+static PyObject *
+builtin_trunc(PyObject *self, PyObject *number)
+{
+        // XXX: The py3k branch gets better errors for this by using
+        // _PyType_Lookup(), but since float's mro isn't set in py2.6,
+        // we just use PyObject_CallMethod here.
+	return PyObject_CallMethod(number, "__trunc__", "");
+}
+
+PyDoc_STRVAR(trunc_doc,
+"trunc(Real) -> Integral\n\
+\n\
+returns the integral closest to x between 0 and x.");
+
 
 static PyObject*
 builtin_sum(PyObject *self, PyObject *args)
@@ -2387,6 +2393,7 @@
  	{"unichr",	builtin_unichr,     METH_VARARGS, unichr_doc},
 #endif
  	{"vars",	builtin_vars,       METH_VARARGS, vars_doc},
+ 	{"trunc",	builtin_trunc,      METH_O, trunc_doc},
   	{"zip",         builtin_zip,        METH_VARARGS, zip_doc},
 	{NULL,		NULL},
 };