codekingpro/portable-devtools
115k
1""" Test functions for limits module.
2
3"""
4import types
5import warnings
6
7import pytest
8
9import numpy as np
10from numpy import double, half, longdouble, single
11from numpy._core import finfo, iinfo
12from numpy.testing import assert_, assert_equal, assert_raises
13
14##################################################
15
16class TestPythonFloat:
17 def test_singleton(self):
18 ftype = finfo(float)
19 ftype2 = finfo(float)
20 assert_equal(id(ftype), id(ftype2))
21
22class TestHalf:
23 def test_singleton(self):
24 ftype = finfo(half)
25 ftype2 = finfo(half)
26 assert_equal(id(ftype), id(ftype2))
27
28class TestSingle:
29 def test_singleton(self):
30 ftype = finfo(single)
31 ftype2 = finfo(single)
32 assert_equal(id(ftype), id(ftype2))
33
34class TestDouble:
35 def test_singleton(self):
36 ftype = finfo(double)
37 ftype2 = finfo(double)
38 assert_equal(id(ftype), id(ftype2))
39
40class TestLongdouble:
41 def test_singleton(self):
42 ftype = finfo(longdouble)
43 ftype2 = finfo(longdouble)
44 assert_equal(id(ftype), id(ftype2))
45
46def assert_finfo_equal(f1, f2):
47 # assert two finfo instances have the same attributes
48 for attr in ('bits', 'eps', 'epsneg', 'iexp', 'machep',
49 'max', 'maxexp', 'min', 'minexp', 'negep', 'nexp',
50 'nmant', 'precision', 'resolution', 'tiny',
51 'smallest_normal', 'smallest_subnormal'):
52 assert_equal(getattr(f1, attr), getattr(f2, attr),
53 f'finfo instances {f1} and {f2} differ on {attr}')
54
55def assert_iinfo_equal(i1, i2):
56 # assert two iinfo instances have the same attributes
57 for attr in ('bits', 'min', 'max'):
58 assert_equal(getattr(i1, attr), getattr(i2, attr),
59 f'iinfo instances {i1} and {i2} differ on {attr}')
60
61class TestFinfo:
62 def test_basic(self):
63 dts = list(zip(['f2', 'f4', 'f8', 'c8', 'c16'],
64 [np.float16, np.float32, np.float64, np.complex64,
65 np.complex128]))
66 for dt1, dt2 in dts:
67 assert_finfo_equal(finfo(dt1), finfo(dt2))
68
69 assert_raises(ValueError, finfo, 'i4')
70
71 def test_regression_gh23108(self):
72 # np.float32(1.0) and np.float64(1.0) have the same hash and are
73 # equal under the == operator
74 f1 = np.finfo(np.float32(1.0))
75 f2 = np.finfo(np.float64(1.0))
76 assert f1 != f2
77
78 def test_regression_gh23867(self):
79 class NonHashableWithDtype:
80 __hash__ = None
81 dtype = np.dtype('float32')
82
83 x = NonHashableWithDtype()
84 assert np.finfo(x) == np.finfo(x.dtype)
85
86
87class TestIinfo:
88 def test_basic(self):
89 dts = list(zip(['i1', 'i2', 'i4', 'i8',
90 'u1', 'u2', 'u4', 'u8'],
91 [np.int8, np.int16, np.int32, np.int64,
92 np.uint8, np.uint16, np.uint32, np.uint64]))
93 for dt1, dt2 in dts:
94 assert_iinfo_equal(iinfo(dt1), iinfo(dt2))
95
96 assert_raises(ValueError, iinfo, 'f4')
97
98 def test_unsigned_max(self):
99 types = np._core.sctypes['uint']
100 for T in types:
101 with np.errstate(over="ignore"):
102 max_calculated = T(0) - T(1)
103 assert_equal(iinfo(T).max, max_calculated)
104
105class TestRepr:
106 def test_iinfo_repr(self):
107 expected = "iinfo(min=-32768, max=32767, dtype=int16)"
108 assert_equal(repr(np.iinfo(np.int16)), expected)
109
110 def test_finfo_repr(self):
111 expected = "finfo(resolution=1e-06, min=-3.4028235e+38,"\
112 " max=3.4028235e+38, dtype=float32)"
113 assert_equal(repr(np.finfo(np.float32)), expected)
114
115
116def test_instances():
117 # Test the finfo and iinfo results on numeric instances agree with
118 # the results on the corresponding types
119
120 for c in [int, np.int16, np.int32, np.int64]:
121 class_iinfo = iinfo(c)
122 instance_iinfo = iinfo(c(12))
123
124 assert_iinfo_equal(class_iinfo, instance_iinfo)
125
126 for c in [float, np.float16, np.float32, np.float64]:
127 class_finfo = finfo(c)
128 instance_finfo = finfo(c(1.2))
129 assert_finfo_equal(class_finfo, instance_finfo)
130
131 with pytest.raises(ValueError):
132 iinfo(10.)
133
134 with pytest.raises(ValueError):
135 iinfo('hi')
136
137 with pytest.raises(ValueError):
138 finfo(np.int64(1))
139
140
141def test_subnormal_warning():
142 """Test that the subnormal is zero warning is not being raised."""
143 with warnings.catch_warnings(record=True) as w:
144 warnings.simplefilter('always')
145 # Test for common float types
146 for dtype in [np.float16, np.float32, np.float64]:
147 f = finfo(dtype)
148 _ = f.smallest_subnormal
149 # Also test longdouble
150 with np.errstate(all='ignore'):
151 fld = finfo(np.longdouble)
152 _ = fld.smallest_subnormal
153 # Check no warnings were raised
154 assert len(w) == 0
155
156
157def test_plausible_finfo():
158 # Assert that finfo returns reasonable results for all types
159 for ftype in np._core.sctypes['float'] + np._core.sctypes['complex']:
160 info = np.finfo(ftype)
161 assert_(info.nmant > 1)
162 assert_(info.minexp < -1)
163 assert_(info.maxexp > 1)
164
165
166class TestRuntimeSubscriptable:
167 def test_finfo_generic(self):
168 assert isinstance(np.finfo[np.float64], types.GenericAlias)
169
170 def test_iinfo_generic(self):
171 assert isinstance(np.iinfo[np.int_], types.GenericAlias)
172 