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/Lib/numbers.py b/Lib/numbers.py
new file mode 100644
index 0000000..d23fa34
--- /dev/null
+++ b/Lib/numbers.py
@@ -0,0 +1,393 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
+
+TODO: Fill out more detailed documentation on the operators."""
+
+from abc import ABCMeta, abstractmethod, abstractproperty
+
+__all__ = ["Number", "Exact", "Inexact",
+           "Complex", "Real", "Rational", "Integral",
+           ]
+
+
+class Number(object):
+    """All numbers inherit from this class.
+
+    If you just want to check if an argument x is a number, without
+    caring what kind, use isinstance(x, Number).
+    """
+    __metaclass__ = ABCMeta
+
+
+class Exact(Number):
+    """Operations on instances of this type are exact.
+
+    As long as the result of a homogenous operation is of the same
+    type, you can assume that it was computed exactly, and there are
+    no round-off errors. Laws like commutativity and associativity
+    hold.
+    """
+
+Exact.register(int)
+Exact.register(long)
+
+
+class Inexact(Number):
+    """Operations on instances of this type are inexact.
+
+    Given X, an instance of Inexact, it is possible that (X + -X) + 3
+    == 3, but X + (-X + 3) == 0. The exact form this error takes will
+    vary by type, but it's generally unsafe to compare this type for
+    equality.
+    """
+
+Inexact.register(complex)
+Inexact.register(float)
+# Inexact.register(decimal.Decimal)
+
+
+class Complex(Number):
+    """Complex defines the operations that work on the builtin complex type.
+
+    In short, those are: a conversion to complex, .real, .imag, +, -,
+    *, /, abs(), .conjugate, ==, and !=.
+
+    If it is given heterogenous arguments, and doesn't have special
+    knowledge about them, it should fall back to the builtin complex
+    type as described below.
+    """
+
+    @abstractmethod
+    def __complex__(self):
+        """Return a builtin complex instance. Called for complex(self)."""
+
+    def __bool__(self):
+        """True if self != 0. Called for bool(self)."""
+        return self != 0
+
+    @abstractproperty
+    def real(self):
+        """Retrieve the real component of this number.
+
+        This should subclass Real.
+        """
+        raise NotImplementedError
+
+    @abstractproperty
+    def imag(self):
+        """Retrieve the real component of this number.
+
+        This should subclass Real.
+        """
+        raise NotImplementedError
+
+    @abstractmethod
+    def __add__(self, other):
+        """self + other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __radd__(self, other):
+        """other + self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __neg__(self):
+        """-self"""
+        raise NotImplementedError
+
+    def __pos__(self):
+        """+self"""
+        raise NotImplementedError
+
+    def __sub__(self, other):
+        """self - other"""
+        return self + -other
+
+    def __rsub__(self, other):
+        """other - self"""
+        return -self + other
+
+    @abstractmethod
+    def __mul__(self, other):
+        """self * other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rmul__(self, other):
+        """other * self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __div__(self, other):
+        """self / other; should promote to float or complex when necessary."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rdiv__(self, other):
+        """other / self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __pow__(self, exponent):
+        """self**exponent; should promote to float or complex when necessary."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rpow__(self, base):
+        """base ** self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __abs__(self):
+        """Returns the Real distance from 0. Called for abs(self)."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def conjugate(self):
+        """(x+y*i).conjugate() returns (x-y*i)."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __eq__(self, other):
+        """self == other"""
+        raise NotImplementedError
+
+    # __ne__ is inherited from object and negates whatever __eq__ does.
+
+Complex.register(complex)
+
+
+class Real(Complex):
+    """To Complex, Real adds the operations that work on real numbers.
+
+    In short, those are: a conversion to float, trunc(), divmod,
+    %, <, <=, >, and >=.
+
+    Real also provides defaults for the derived operations.
+    """
+
+    @abstractmethod
+    def __float__(self):
+        """Any Real can be converted to a native float object.
+
+        Called for float(self)."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __trunc__(self):
+        """trunc(self): Truncates self to an Integral.
+
+        Returns an Integral i such that:
+          * i>0 iff self>0;
+          * abs(i) <= abs(self);
+          * for any Integral j satisfying the first two conditions,
+            abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
+        i.e. "truncate towards 0".
+        """
+        raise NotImplementedError
+
+    @abstractmethod
+    def __floor__(self):
+        """Finds the greatest Integral <= self."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __ceil__(self):
+        """Finds the least Integral >= self."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __round__(self, ndigits=None):
+        """Rounds self to ndigits decimal places, defaulting to 0.
+
+        If ndigits is omitted or None, returns an Integral, otherwise
+        returns a Real. Rounds half toward even.
+        """
+        raise NotImplementedError
+
+    def __divmod__(self, other):
+        """divmod(self, other): The pair (self // other, self % other).
+
+        Sometimes this can be computed faster than the pair of
+        operations.
+        """
+        return (self // other, self % other)
+
+    def __rdivmod__(self, other):
+        """divmod(other, self): The pair (self // other, self % other).
+
+        Sometimes this can be computed faster than the pair of
+        operations.
+        """
+        return (other // self, other % self)
+
+    @abstractmethod
+    def __floordiv__(self, other):
+        """self // other: The floor() of self/other."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rfloordiv__(self, other):
+        """other // self: The floor() of other/self."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __mod__(self, other):
+        """self % other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rmod__(self, other):
+        """other % self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __lt__(self, other):
+        """self < other
+
+        < on Reals defines a total ordering, except perhaps for NaN."""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __le__(self, other):
+        """self <= other"""
+        raise NotImplementedError
+
+    # Concrete implementations of Complex abstract methods.
+    def __complex__(self):
+        """complex(self) == complex(float(self), 0)"""
+        return complex(float(self))
+
+    @property
+    def real(self):
+        """Real numbers are their real component."""
+        return +self
+
+    @property
+    def imag(self):
+        """Real numbers have no imaginary component."""
+        return 0
+
+    def conjugate(self):
+        """Conjugate is a no-op for Reals."""
+        return +self
+
+Real.register(float)
+# Real.register(decimal.Decimal)
+
+
+class Rational(Real, Exact):
+    """.numerator and .denominator should be in lowest terms."""
+
+    @abstractproperty
+    def numerator(self):
+        raise NotImplementedError
+
+    @abstractproperty
+    def denominator(self):
+        raise NotImplementedError
+
+    # Concrete implementation of Real's conversion to float.
+    def __float__(self):
+        """float(self) = self.numerator / self.denominator"""
+        return self.numerator / self.denominator
+
+
+class Integral(Rational):
+    """Integral adds a conversion to long and the bit-string operations."""
+
+    @abstractmethod
+    def __long__(self):
+        """long(self)"""
+        raise NotImplementedError
+
+    def __index__(self):
+        """index(self)"""
+        return long(self)
+
+    @abstractmethod
+    def __pow__(self, exponent, modulus=None):
+        """self ** exponent % modulus, but maybe faster.
+
+        Accept the modulus argument if you want to support the
+        3-argument version of pow(). Raise a TypeError if exponent < 0
+        or any argument isn't Integral. Otherwise, just implement the
+        2-argument version described in Complex.
+        """
+        raise NotImplementedError
+
+    @abstractmethod
+    def __lshift__(self, other):
+        """self << other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rlshift__(self, other):
+        """other << self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rshift__(self, other):
+        """self >> other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rrshift__(self, other):
+        """other >> self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __and__(self, other):
+        """self & other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rand__(self, other):
+        """other & self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __xor__(self, other):
+        """self ^ other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __rxor__(self, other):
+        """other ^ self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __or__(self, other):
+        """self | other"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __ror__(self, other):
+        """other | self"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def __invert__(self):
+        """~self"""
+        raise NotImplementedError
+
+    # Concrete implementations of Rational and Real abstract methods.
+    def __float__(self):
+        """float(self) == float(long(self))"""
+        return float(long(self))
+
+    @property
+    def numerator(self):
+        """Integers are their own numerators."""
+        return +self
+
+    @property
+    def denominator(self):
+        """Integers have a denominator of 1."""
+        return 1
+
+Integral.register(int)
+Integral.register(long)
diff --git a/Lib/test/test_abstract_numbers.py b/Lib/test/test_abstract_numbers.py
new file mode 100644
index 0000000..19bfc79
--- /dev/null
+++ b/Lib/test/test_abstract_numbers.py
@@ -0,0 +1,62 @@
+"""Unit tests for numbers.py."""
+
+import unittest
+from test import test_support
+from numbers import Number
+from numbers import Exact, Inexact
+from numbers import Complex, Real, Rational, Integral
+import operator
+
+class TestNumbers(unittest.TestCase):
+    def test_int(self):
+        self.failUnless(issubclass(int, Integral))
+        self.failUnless(issubclass(int, Complex))
+        self.failUnless(issubclass(int, Exact))
+        self.failIf(issubclass(int, Inexact))
+
+        self.assertEqual(7, int(7).real)
+        self.assertEqual(0, int(7).imag)
+        self.assertEqual(7, int(7).conjugate())
+        self.assertEqual(7, int(7).numerator)
+        self.assertEqual(1, int(7).denominator)
+
+    def test_long(self):
+        self.failUnless(issubclass(long, Integral))
+        self.failUnless(issubclass(long, Complex))
+        self.failUnless(issubclass(long, Exact))
+        self.failIf(issubclass(long, Inexact))
+
+        self.assertEqual(7, long(7).real)
+        self.assertEqual(0, long(7).imag)
+        self.assertEqual(7, long(7).conjugate())
+        self.assertEqual(7, long(7).numerator)
+        self.assertEqual(1, long(7).denominator)
+
+    def test_float(self):
+        self.failIf(issubclass(float, Rational))
+        self.failUnless(issubclass(float, Real))
+        self.failIf(issubclass(float, Exact))
+        self.failUnless(issubclass(float, Inexact))
+
+        self.assertEqual(7.3, float(7.3).real)
+        self.assertEqual(0, float(7.3).imag)
+        self.assertEqual(7.3, float(7.3).conjugate())
+
+    def test_complex(self):
+        self.failIf(issubclass(complex, Real))
+        self.failUnless(issubclass(complex, Complex))
+        self.failIf(issubclass(complex, Exact))
+        self.failUnless(issubclass(complex, Inexact))
+
+        c1, c2 = complex(3, 2), complex(4,1)
+        # XXX: This is not ideal, but see the comment in builtin_trunc().
+        self.assertRaises(AttributeError, trunc, c1)
+        self.assertRaises(TypeError, float, c1)
+        self.assertRaises(TypeError, int, c1)
+
+def test_main():
+    test_support.run_unittest(TestNumbers)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 52178c8..c5a1cc3 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1450,11 +1450,13 @@
                     else:
                         self.assertAlmostEqual(pow(x, y, z), 24.0)
 
+        self.assertAlmostEqual(pow(-1, 0.5), 1j)
+        self.assertAlmostEqual(pow(-1, 1./3), 0.5 + 0.8660254037844386j)
+
         self.assertRaises(TypeError, pow, -1, -2, 3)
         self.assertRaises(ValueError, pow, 1, 2, 0)
         self.assertRaises(TypeError, pow, -1L, -2L, 3L)
         self.assertRaises(ValueError, pow, 1L, 2L, 0L)
-        self.assertRaises(ValueError, pow, -342.43, 0.234)
 
         self.assertRaises(TypeError, pow)
 
@@ -1622,6 +1624,7 @@
 
     def test_round(self):
         self.assertEqual(round(0.0), 0.0)
+        self.assertEqual(type(round(0.0)), float)  # Will be int in 3.0.
         self.assertEqual(round(1.0), 1.0)
         self.assertEqual(round(10.0), 10.0)
         self.assertEqual(round(1000000000.0), 1000000000.0)
@@ -1650,12 +1653,50 @@
         self.assertEqual(round(-999999999.9), -1000000000.0)
 
         self.assertEqual(round(-8.0, -1), -10.0)
+        self.assertEqual(type(round(-8.0, -1)), float)
+
+        self.assertEqual(type(round(-8.0, 0)), float)
+        self.assertEqual(type(round(-8.0, 1)), float)
+
+        # Check even / odd rounding behaviour
+        self.assertEqual(round(5.5), 6)
+        self.assertEqual(round(6.5), 6)
+        self.assertEqual(round(-5.5), -6)
+        self.assertEqual(round(-6.5), -6)
+
+        # Check behavior on ints
+        self.assertEqual(round(0), 0)
+        self.assertEqual(round(8), 8)
+        self.assertEqual(round(-8), -8)
+        self.assertEqual(type(round(0)), float)  # Will be int in 3.0.
+        self.assertEqual(type(round(-8, -1)), float)
+        self.assertEqual(type(round(-8, 0)), float)
+        self.assertEqual(type(round(-8, 1)), float)
 
         # test new kwargs
         self.assertEqual(round(number=-8.0, ndigits=-1), -10.0)
 
         self.assertRaises(TypeError, round)
 
+        # test generic rounding delegation for reals
+        class TestRound(object):
+            def __round__(self):
+                return 23
+
+        class TestNoRound(object):
+            pass
+
+        self.assertEqual(round(TestRound()), 23)
+
+        self.assertRaises(TypeError, round, 1, 2, 3)
+        # XXX: This is not ideal, but see the comment in builtin_round().
+        self.assertRaises(AttributeError, round, TestNoRound())
+
+        t = TestNoRound()
+        t.__round__ = lambda *args: args
+        self.assertEquals((), round(t))
+        self.assertEquals((0,), round(t, 0))
+
     def test_setattr(self):
         setattr(sys, 'spam', 1)
         self.assertEqual(sys.spam, 1)
@@ -1697,6 +1738,38 @@
                 raise ValueError
         self.assertRaises(ValueError, sum, BadSeq())
 
+    def test_trunc(self):
+
+        self.assertEqual(trunc(1), 1)
+        self.assertEqual(trunc(-1), -1)
+        self.assertEqual(type(trunc(1)), int)
+        self.assertEqual(type(trunc(1.5)), int)
+        self.assertEqual(trunc(1.5), 1)
+        self.assertEqual(trunc(-1.5), -1)
+        self.assertEqual(trunc(1.999999), 1)
+        self.assertEqual(trunc(-1.999999), -1)
+        self.assertEqual(trunc(-0.999999), -0)
+        self.assertEqual(trunc(-100.999), -100)
+
+        class TestTrunc(object):
+            def __trunc__(self):
+                return 23
+
+        class TestNoTrunc(object):
+            pass
+
+        self.assertEqual(trunc(TestTrunc()), 23)
+
+        self.assertRaises(TypeError, trunc)
+        self.assertRaises(TypeError, trunc, 1, 2)
+        # XXX: This is not ideal, but see the comment in builtin_trunc().
+        self.assertRaises(AttributeError, trunc, TestNoTrunc())
+
+        t = TestNoTrunc()
+        t.__trunc__ = lambda *args: args
+        self.assertEquals((), trunc(t))
+        self.assertRaises(TypeError, trunc, t, 0)
+
     def test_tuple(self):
         self.assertEqual(tuple(()), ())
         t0_3 = (0, 1, 2, 3)
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index ae132ad..29515c7 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -385,7 +385,9 @@
                      "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.",
                      "math.sin(huge)", "math.sin(mhuge)",
                      "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better
-                     "math.floor(huge)", "math.floor(mhuge)"]:
+                     # math.floor() of an int returns an int now
+                     ##"math.floor(huge)", "math.floor(mhuge)",
+                     ]:
 
             self.assertRaises(OverflowError, eval, test, namespace)
 
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index d86298d..98e4623 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -58,6 +58,19 @@
         self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
         self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
 
+        class TestCeil(object):
+            def __ceil__(self):
+                return 42
+        class TestNoCeil(object):
+            pass
+        self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42)
+        self.assertRaises(TypeError, math.ceil, TestNoCeil())
+
+        t = TestNoCeil()
+        t.__ceil__ = lambda *args: args
+        self.assertRaises(TypeError, math.ceil, t)
+        self.assertRaises(TypeError, math.ceil, t, 0)
+
     def testCos(self):
         self.assertRaises(TypeError, math.cos)
         self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0)
@@ -101,6 +114,19 @@
         self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
         self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
 
+        class TestFloor(object):
+            def __floor__(self):
+                return 42
+        class TestNoFloor(object):
+            pass
+        self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42)
+        self.assertRaises(TypeError, math.floor, TestNoFloor())
+
+        t = TestNoFloor()
+        t.__floor__ = lambda *args: args
+        self.assertRaises(TypeError, math.floor, t)
+        self.assertRaises(TypeError, math.floor, t, 0)
+
     def testFmod(self):
         self.assertRaises(TypeError, math.fmod)
         self.ftest('fmod(10,1)', math.fmod(10,1), 0)
diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py
index 9dfed7b..5a82780 100644
--- a/Lib/test/test_unittest.py
+++ b/Lib/test/test_unittest.py
@@ -2264,13 +2264,34 @@
         expected = ['startTest', 'test', 'stopTest']
         self.assertEqual(events, expected)
 
+class Test_Assertions(TestCase):
+    def test_AlmostEqual(self):
+        self.failUnlessAlmostEqual(1.00000001, 1.0)
+        self.failIfAlmostEqual(1.0000001, 1.0)
+        self.assertRaises(AssertionError,
+                          self.failUnlessAlmostEqual, 1.0000001, 1.0)
+        self.assertRaises(AssertionError,
+                          self.failIfAlmostEqual, 1.00000001, 1.0)
+
+        self.failUnlessAlmostEqual(1.1, 1.0, places=0)
+        self.assertRaises(AssertionError,
+                          self.failUnlessAlmostEqual, 1.1, 1.0, places=1)
+
+        self.failUnlessAlmostEqual(0, .1+.1j, places=0)
+        self.failIfAlmostEqual(0, .1+.1j, places=1)
+        self.assertRaises(AssertionError,
+                          self.failUnlessAlmostEqual, 0, .1+.1j, places=1)
+        self.assertRaises(AssertionError,
+                          self.failIfAlmostEqual, 0, .1+.1j, places=0)
+
 ######################################################################
 ## Main
 ######################################################################
 
 def test_main():
     test_support.run_unittest(Test_TestCase, Test_TestLoader,
-        Test_TestSuite, Test_TestResult, Test_FunctionTestCase)
+        Test_TestSuite, Test_TestResult, Test_FunctionTestCase,
+        Test_Assertions)
 
 if __name__ == "__main__":
     test_main()
diff --git a/Lib/unittest.py b/Lib/unittest.py
index 7ea240c..eccefe6 100644
--- a/Lib/unittest.py
+++ b/Lib/unittest.py
@@ -358,7 +358,7 @@
            Note that decimal places (from zero) are usually not the same
            as significant digits (measured from the most signficant digit).
         """
-        if round(second-first, places) != 0:
+        if round(abs(second-first), places) != 0:
             raise self.failureException, \
                   (msg or '%r != %r within %r places' % (first, second, places))
 
@@ -370,7 +370,7 @@
            Note that decimal places (from zero) are usually not the same
            as significant digits (measured from the most signficant digit).
         """
-        if round(second-first, places) == 0:
+        if round(abs(second-first), places) == 0:
             raise self.failureException, \
                   (msg or '%r == %r within %r places' % (first, second, places))