| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | """Unit tests for numbers.py.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  | import abc | 
					
						
							| 
									
										
										
										
											2008-02-01 08:12:03 +00:00
										 |  |  | import math | 
					
						
							|  |  |  | import operator | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TestNumbers(unittest.TestCase): | 
					
						
							|  |  |  |     def test_int(self): | 
					
						
							| 
									
										
										
										
											2009-06-30 23:06:06 +00:00
										 |  |  |         self.assertTrue(issubclass(int, Integral)) | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  |         self.assertTrue(issubclass(int, Rational)) | 
					
						
							|  |  |  |         self.assertTrue(issubclass(int, Real)) | 
					
						
							| 
									
										
										
										
											2009-06-30 23:06:06 +00:00
										 |  |  |         self.assertTrue(issubclass(int, Complex)) | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  |         self.assertTrue(issubclass(int, Number)) | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(7, int(7).real) | 
					
						
							|  |  |  |         self.assertEqual(0, int(7).imag) | 
					
						
							|  |  |  |         self.assertEqual(7, int(7).conjugate()) | 
					
						
							| 
									
										
										
										
											2011-05-30 19:22:53 -05:00
										 |  |  |         self.assertEqual(-7, int(-7).conjugate()) | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  |         self.assertEqual(7, int(7).numerator) | 
					
						
							|  |  |  |         self.assertEqual(1, int(7).denominator) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_float(self): | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  |         self.assertFalse(issubclass(float, Integral)) | 
					
						
							| 
									
										
										
										
											2009-06-30 23:06:06 +00:00
										 |  |  |         self.assertFalse(issubclass(float, Rational)) | 
					
						
							|  |  |  |         self.assertTrue(issubclass(float, Real)) | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  |         self.assertTrue(issubclass(float, Complex)) | 
					
						
							|  |  |  |         self.assertTrue(issubclass(float, Number)) | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(7.3, float(7.3).real) | 
					
						
							|  |  |  |         self.assertEqual(0, float(7.3).imag) | 
					
						
							|  |  |  |         self.assertEqual(7.3, float(7.3).conjugate()) | 
					
						
							| 
									
										
										
										
											2011-05-30 19:22:53 -05:00
										 |  |  |         self.assertEqual(-7.3, float(-7.3).conjugate()) | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_complex(self): | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  |         self.assertFalse(issubclass(complex, Integral)) | 
					
						
							|  |  |  |         self.assertFalse(issubclass(complex, Rational)) | 
					
						
							| 
									
										
										
										
											2009-06-30 23:06:06 +00:00
										 |  |  |         self.assertFalse(issubclass(complex, Real)) | 
					
						
							|  |  |  |         self.assertTrue(issubclass(complex, Complex)) | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  |         self.assertTrue(issubclass(complex, Number)) | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         c1, c2 = complex(3, 2), complex(4,1) | 
					
						
							| 
									
										
										
										
											2008-02-01 08:12:03 +00:00
										 |  |  |         # XXX: This is not ideal, but see the comment in math_trunc(). | 
					
						
							|  |  |  |         self.assertRaises(TypeError, math.trunc, c1) | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  |         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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-25 22:35:05 +08:00
										 |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-30 17:45:54 +00:00
										 |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     unittest.main() |