| """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.assertIsSubclass(int, Integral) | |
| self.assertIsSubclass(int, Rational) | |
| self.assertIsSubclass(int, Real) | |
| self.assertIsSubclass(int, Complex) | |
| self.assertIsSubclass(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.assertNotIsSubclass(float, Integral) | |
| self.assertNotIsSubclass(float, Rational) | |
| self.assertIsSubclass(float, Real) | |
| self.assertIsSubclass(float, Complex) | |
| self.assertIsSubclass(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.assertNotIsSubclass(complex, Integral) | |
| self.assertNotIsSubclass(complex, Rational) | |
| self.assertNotIsSubclass(complex, Real) | |
| self.assertIsSubclass(complex, Complex) | |
| self.assertIsSubclass(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() |