summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-01-25 14:49:46 (GMT)
committerGitHub <noreply@github.com>2024-01-25 14:49:46 (GMT)
commit709f17b7cc9dd26554de5fd64adb42d28c455107 (patch)
treed92b2cc477331481f45ba3529e6988d73bbb0ccc
parent279bbd2134c1cd56bfcf525b61b76d86e4e3b26b (diff)
downloadcpython-709f17b7cc9dd26554de5fd64adb42d28c455107.zip
cpython-709f17b7cc9dd26554de5fd64adb42d28c455107.tar.gz
cpython-709f17b7cc9dd26554de5fd64adb42d28c455107.tar.bz2
[3.11] gh-77465: Increase test coverage for the numbers module (GH-111738) (GH-114557)
(cherry picked from commit e721adf4bd47b20ba0a93ad6471084de31bf20c7) Co-authored-by: AN Long <aisk@users.noreply.github.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
-rw-r--r--Lib/test/test_abstract_numbers.py158
1 files changed, 157 insertions, 1 deletions
diff --git a/Lib/test/test_abstract_numbers.py b/Lib/test/test_abstract_numbers.py
index 2e06f0d..72232b6 100644
--- a/Lib/test/test_abstract_numbers.py
+++ b/Lib/test/test_abstract_numbers.py
@@ -1,14 +1,34 @@
"""Unit tests for numbers.py."""
+import abc
import math
import operator
import unittest
-from numbers import Complex, Real, Rational, Integral
+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)
@@ -18,8 +38,11 @@ class TestNumbers(unittest.TestCase):
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)
@@ -27,8 +50,11 @@ class TestNumbers(unittest.TestCase):
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().
@@ -40,5 +66,135 @@ class TestNumbers(unittest.TestCase):
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()