| """Unit tests for numbers.py.""" |
| |
| import abc |
| import math |
| import operator |
| import unittest |
| from numbers import Complex, Real, Rational, Integral, Number |
| |
| |
| def concretize(cls): |
| def not_implemented(*args, **kwargs): |
| raise NotImplementedError() |
| |
| for name in dir(cls): |
| try: |
| value = getattr(cls, name) |
| if value.__isabstractmethod__: |
| setattr(cls, name, not_implemented) |
| except AttributeError: |
| pass |
| abc.update_abstractmethods(cls) |
| return cls |
| |
| |
| class TestNumbers(unittest.TestCase): |
| def test_int(self): |
| self.assertTrue(issubclass(int, Integral)) |
| self.assertTrue(issubclass(int, Rational)) |
| self.assertTrue(issubclass(int, Real)) |
| self.assertTrue(issubclass(int, Complex)) |
| self.assertTrue(issubclass(int, Number)) |
| |
| self.assertEqual(7, int(7).real) |
| self.assertEqual(0, int(7).imag) |
| self.assertEqual(7, int(7).conjugate()) |
| self.assertEqual(-7, int(-7).conjugate()) |
| self.assertEqual(7, int(7).numerator) |
| self.assertEqual(1, int(7).denominator) |
| |
| def test_float(self): |
| self.assertFalse(issubclass(float, Integral)) |
| self.assertFalse(issubclass(float, Rational)) |
| self.assertTrue(issubclass(float, Real)) |
| self.assertTrue(issubclass(float, Complex)) |
| self.assertTrue(issubclass(float, Number)) |
| |
| self.assertEqual(7.3, float(7.3).real) |
| self.assertEqual(0, float(7.3).imag) |
| self.assertEqual(7.3, float(7.3).conjugate()) |
| self.assertEqual(-7.3, float(-7.3).conjugate()) |
| |
| def test_complex(self): |
| self.assertFalse(issubclass(complex, Integral)) |
| self.assertFalse(issubclass(complex, Rational)) |
| self.assertFalse(issubclass(complex, Real)) |
| self.assertTrue(issubclass(complex, Complex)) |
| self.assertTrue(issubclass(complex, Number)) |
| |
| c1, c2 = complex(3, 2), complex(4,1) |
| # XXX: This is not ideal, but see the comment in math_trunc(). |
| self.assertRaises(TypeError, math.trunc, c1) |
| self.assertRaises(TypeError, operator.mod, c1, c2) |
| self.assertRaises(TypeError, divmod, c1, c2) |
| self.assertRaises(TypeError, operator.floordiv, c1, c2) |
| self.assertRaises(TypeError, float, c1) |
| self.assertRaises(TypeError, int, c1) |
| |
| |
| class TestNumbersDefaultMethods(unittest.TestCase): |
| def test_complex(self): |
| @concretize |
| class MyComplex(Complex): |
| def __init__(self, real, imag): |
| self.r = real |
| self.i = imag |
| |
| @property |
| def real(self): |
| return self.r |
| |
| @property |
| def imag(self): |
| return self.i |
| |
| def __add__(self, other): |
| if isinstance(other, Complex): |
| return MyComplex(self.imag + other.imag, |
| self.real + other.real) |
| raise NotImplementedError |
| |
| def __neg__(self): |
| return MyComplex(-self.real, -self.imag) |
| |
| def __eq__(self, other): |
| if isinstance(other, Complex): |
| return self.imag == other.imag and self.real == other.real |
| if isinstance(other, Number): |
| return self.imag == 0 and self.real == other.real |
| |
| # test __bool__ |
| self.assertTrue(bool(MyComplex(1, 1))) |
| self.assertTrue(bool(MyComplex(0, 1))) |
| self.assertTrue(bool(MyComplex(1, 0))) |
| self.assertFalse(bool(MyComplex(0, 0))) |
| |
| # test __sub__ |
| self.assertEqual(MyComplex(2, 3) - complex(1, 2), MyComplex(1, 1)) |
| |
| # test __rsub__ |
| self.assertEqual(complex(2, 3) - MyComplex(1, 2), MyComplex(1, 1)) |
| |
| def test_real(self): |
| @concretize |
| class MyReal(Real): |
| def __init__(self, n): |
| self.n = n |
| |
| def __pos__(self): |
| return self.n |
| |
| def __float__(self): |
| return float(self.n) |
| |
| def __floordiv__(self, other): |
| return self.n // other |
| |
| def __rfloordiv__(self, other): |
| return other // self.n |
| |
| def __mod__(self, other): |
| return self.n % other |
| |
| def __rmod__(self, other): |
| return other % self.n |
| |
| # test __divmod__ |
| self.assertEqual(divmod(MyReal(3), 2), (1, 1)) |
| |
| # test __rdivmod__ |
| self.assertEqual(divmod(3, MyReal(2)), (1, 1)) |
| |
| # test __complex__ |
| self.assertEqual(complex(MyReal(1)), 1+0j) |
| |
| # test real |
| self.assertEqual(MyReal(3).real, 3) |
| |
| # test imag |
| self.assertEqual(MyReal(3).imag, 0) |
| |
| # test conjugate |
| self.assertEqual(MyReal(123).conjugate(), 123) |
| |
| |
| def test_rational(self): |
| @concretize |
| class MyRational(Rational): |
| def __init__(self, numerator, denominator): |
| self.n = numerator |
| self.d = denominator |
| |
| @property |
| def numerator(self): |
| return self.n |
| |
| @property |
| def denominator(self): |
| return self.d |
| |
| # test__float__ |
| self.assertEqual(float(MyRational(5, 2)), 2.5) |
| |
| |
| def test_integral(self): |
| @concretize |
| class MyIntegral(Integral): |
| def __init__(self, n): |
| self.n = n |
| |
| def __pos__(self): |
| return self.n |
| |
| def __int__(self): |
| return self.n |
| |
| # test __index__ |
| self.assertEqual(operator.index(MyIntegral(123)), 123) |
| |
| # test __float__ |
| self.assertEqual(float(MyIntegral(123)), 123.0) |
| |
| # test numerator |
| self.assertEqual(MyIntegral(123).numerator, 123) |
| |
| # test denominator |
| self.assertEqual(MyIntegral(123).denominator, 1) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |