|
3 | 3 | from test import support
|
4 | 4 | from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
|
5 | 5 | INVALID_UNDERSCORE_LITERALS)
|
| 6 | +from test.support import import_helper |
| 7 | +from test.test_capi.test_getargs import (BadComplex, BadComplex2, Complex, |
| 8 | + FloatSubclass, Float, BadFloat, |
| 9 | + BadFloat2, ComplexSubclass) |
6 | 10 |
|
7 | 11 | from random import random
|
8 | 12 | from math import atan2, isnan, copysign
|
9 | 13 | import operator
|
10 | 14 |
|
| 15 | +_testcapi = import_helper.import_module('_testcapi') |
| 16 | + |
11 | 17 | INF = float("inf")
|
12 | 18 | NAN = float("nan")
|
13 | 19 | # These tests ensure that complex math does the right thing
|
|
20 | 26 | (1, 0+0j),
|
21 | 27 | )
|
22 | 28 |
|
| 29 | +NULL = None |
| 30 | + |
23 | 31 | class ComplexTest(unittest.TestCase):
|
24 | 32 |
|
25 | 33 | def assertAlmostEqual(self, a, b):
|
@@ -72,6 +80,15 @@ def assertFloatsAreIdentical(self, x, y):
|
72 | 80 | msg += ': zeros have different signs'
|
73 | 81 | self.fail(msg.format(x, y))
|
74 | 82 |
|
| 83 | + def assertComplexesAreIdentical(self, x, y): |
| 84 | + """assert that complex numbers x and y are identical |
| 85 | +
|
| 86 | + I.e. they have identical real and imag components. |
| 87 | +
|
| 88 | + """ |
| 89 | + (self.assertFloatsAreIdentical(x.real, y.real) |
| 90 | + and self.assertFloatsAreIdentical(x.imag, y.imag)) |
| 91 | + |
75 | 92 | def assertClose(self, x, y, eps=1e-9):
|
76 | 93 | """Return true iff complexes x and y "are close"."""
|
77 | 94 | self.assertCloseAbs(x.real, y.real, eps)
|
@@ -792,5 +809,114 @@ def test_format(self):
|
792 | 809 | self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j')
|
793 | 810 |
|
794 | 811 |
|
| 812 | +class CAPIComplexTest(ComplexTest): |
| 813 | + def test_check(self): |
| 814 | + # Test PyComplex_Check() |
| 815 | + check = _testcapi.complex_check |
| 816 | + |
| 817 | + self.assertTrue(check(1+2j)) |
| 818 | + self.assertTrue(check(ComplexSubclass(1+2j))) |
| 819 | + self.assertFalse(check(Complex())) |
| 820 | + self.assertFalse(check(3)) |
| 821 | + self.assertFalse(check([])) |
| 822 | + self.assertFalse(check(object())) |
| 823 | + |
| 824 | + # CRASHES check(NULL) |
| 825 | + |
| 826 | + def test_checkexact(self): |
| 827 | + # PyComplex_CheckExact() |
| 828 | + checkexact = _testcapi.complex_checkexact |
| 829 | + |
| 830 | + self.assertTrue(checkexact(1+2j)) |
| 831 | + self.assertFalse(checkexact(ComplexSubclass(1+2j))) |
| 832 | + self.assertFalse(checkexact(Complex())) |
| 833 | + self.assertFalse(checkexact(3)) |
| 834 | + self.assertFalse(checkexact([])) |
| 835 | + self.assertFalse(checkexact(object())) |
| 836 | + |
| 837 | + # CRASHES checkexact(NULL) |
| 838 | + |
| 839 | + def test_fromccomplex(self): |
| 840 | + # Test PyComplex_FromCComplex() |
| 841 | + fromccomplex = _testcapi.complex_fromccomplex |
| 842 | + |
| 843 | + self.assertComplexesAreIdentical(fromccomplex(1+2j), 1.0+2.0j) |
| 844 | + |
| 845 | + def test_fromdoubles(self): |
| 846 | + # Test PyComplex_FromDoubles() |
| 847 | + fromdoubles = _testcapi.complex_fromdoubles |
| 848 | + |
| 849 | + self.assertComplexesAreIdentical(fromdoubles(1.0, 2.0), 1.0+2.0j) |
| 850 | + |
| 851 | + def test_realasdouble(self): |
| 852 | + # Test PyComplex_RealAsDouble() |
| 853 | + realasdouble = _testcapi.complex_realasdouble |
| 854 | + |
| 855 | + self.assertFloatsAreIdentical(realasdouble(1+2j), 1.0) |
| 856 | + self.assertFloatsAreIdentical(realasdouble(1), 1.0) |
| 857 | + self.assertFloatsAreIdentical(realasdouble(-1), -1.0) |
| 858 | + # Function doesn't support classes with __complex__ dunder, see #109598 |
| 859 | + #self.assertFloatsAreIdentical(realasdouble(Complex()), 4.25) |
| 860 | + #self.assertFloatsAreIdentical(realasdouble(3.14), 3.14) |
| 861 | + #self.assertFloatsAreIdentical(realasdouble(FloatSubclass(3.14)), 3.14) |
| 862 | + #self.assertFloatsAreIdentical(realasdouble(Float()), 4.25) |
| 863 | + #with self.assertWarns(DeprecationWarning): |
| 864 | + # self.assertFloatsAreIdentical(realasdouble(BadComplex2()), 4.25) |
| 865 | + #with self.assertWarns(DeprecationWarning): |
| 866 | + # self.assertFloatsAreIdentical(realasdouble(BadFloat2()), 4.25) |
| 867 | + self.assertRaises(TypeError, realasdouble, BadComplex()) |
| 868 | + self.assertRaises(TypeError, realasdouble, BadFloat()) |
| 869 | + self.assertRaises(TypeError, realasdouble, object()) |
| 870 | + |
| 871 | + # CRASHES realasdouble(NULL) |
| 872 | + |
| 873 | + def test_imagasdouble(self): |
| 874 | + # Test PyComplex_ImagAsDouble() |
| 875 | + imagasdouble = _testcapi.complex_imagasdouble |
| 876 | + |
| 877 | + self.assertFloatsAreIdentical(imagasdouble(1+2j), 2.0) |
| 878 | + self.assertFloatsAreIdentical(imagasdouble(1), 0.0) |
| 879 | + self.assertFloatsAreIdentical(imagasdouble(-1), 0.0) |
| 880 | + # Function doesn't support classes with __complex__ dunder, see #109598 |
| 881 | + #self.assertFloatsAreIdentical(imagasdouble(Complex()), 0.5) |
| 882 | + #self.assertFloatsAreIdentical(imagasdouble(3.14), 0.0) |
| 883 | + #self.assertFloatsAreIdentical(imagasdouble(FloatSubclass(3.14)), 0.0) |
| 884 | + #self.assertFloatsAreIdentical(imagasdouble(Float()), 0.0) |
| 885 | + #with self.assertWarns(DeprecationWarning): |
| 886 | + # self.assertFloatsAreIdentical(imagasdouble(BadComplex2()), 0.5) |
| 887 | + #with self.assertWarns(DeprecationWarning): |
| 888 | + # self.assertFloatsAreIdentical(imagasdouble(BadFloat2()), 0.0) |
| 889 | + # Function returns 0.0 anyway, see #109598 |
| 890 | + #self.assertRaises(TypeError, imagasdouble, BadComplex()) |
| 891 | + #self.assertRaises(TypeError, imagasdouble, BadFloat()) |
| 892 | + #self.assertRaises(TypeError, imagasdouble, object()) |
| 893 | + self.assertFloatsAreIdentical(imagasdouble(BadComplex()), 0.0) |
| 894 | + self.assertFloatsAreIdentical(imagasdouble(BadFloat()), 0.0) |
| 895 | + self.assertFloatsAreIdentical(imagasdouble(object()), 0.0) |
| 896 | + |
| 897 | + # CRASHES imagasdouble(NULL) |
| 898 | + |
| 899 | + def test_asccomplex(self): |
| 900 | + # Test PyComplex_AsCComplex() |
| 901 | + asccomplex = _testcapi.complex_asccomplex |
| 902 | + |
| 903 | + self.assertComplexesAreIdentical(asccomplex(1+2j), 1.0+2.0j) |
| 904 | + self.assertComplexesAreIdentical(asccomplex(1), 1.0+0.0j) |
| 905 | + self.assertComplexesAreIdentical(asccomplex(-1), -1.0+0.0j) |
| 906 | + self.assertComplexesAreIdentical(asccomplex(Complex()), 4.25+0.5j) |
| 907 | + self.assertComplexesAreIdentical(asccomplex(3.14), 3.14+0.0j) |
| 908 | + self.assertComplexesAreIdentical(asccomplex(FloatSubclass(3.14)), 3.14+0.0j) |
| 909 | + self.assertComplexesAreIdentical(asccomplex(Float()), 4.25+0.0j) |
| 910 | + with self.assertWarns(DeprecationWarning): |
| 911 | + self.assertComplexesAreIdentical(asccomplex(BadComplex2()), 4.25+0.5j) |
| 912 | + with self.assertWarns(DeprecationWarning): |
| 913 | + self.assertComplexesAreIdentical(asccomplex(BadFloat2()), 4.25+0.0j) |
| 914 | + self.assertRaises(TypeError, asccomplex, BadComplex()) |
| 915 | + self.assertRaises(TypeError, asccomplex, BadFloat()) |
| 916 | + self.assertRaises(TypeError, asccomplex, object()) |
| 917 | + |
| 918 | + # CRASHES asccomplex(NULL) |
| 919 | + |
| 920 | + |
795 | 921 | if __name__ == "__main__":
|
796 | 922 | unittest.main()
|
0 commit comments