|
1 |
|
2 import unittest, struct |
|
3 from test import test_support |
|
4 |
|
5 class FormatFunctionsTestCase(unittest.TestCase): |
|
6 |
|
7 def setUp(self): |
|
8 self.save_formats = {'double':float.__getformat__('double'), |
|
9 'float':float.__getformat__('float')} |
|
10 |
|
11 def tearDown(self): |
|
12 float.__setformat__('double', self.save_formats['double']) |
|
13 float.__setformat__('float', self.save_formats['float']) |
|
14 |
|
15 def test_getformat(self): |
|
16 self.assert_(float.__getformat__('double') in |
|
17 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian']) |
|
18 self.assert_(float.__getformat__('float') in |
|
19 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian']) |
|
20 self.assertRaises(ValueError, float.__getformat__, 'chicken') |
|
21 self.assertRaises(TypeError, float.__getformat__, 1) |
|
22 |
|
23 def test_setformat(self): |
|
24 for t in 'double', 'float': |
|
25 float.__setformat__(t, 'unknown') |
|
26 if self.save_formats[t] == 'IEEE, big-endian': |
|
27 self.assertRaises(ValueError, float.__setformat__, |
|
28 t, 'IEEE, little-endian') |
|
29 elif self.save_formats[t] == 'IEEE, little-endian': |
|
30 self.assertRaises(ValueError, float.__setformat__, |
|
31 t, 'IEEE, big-endian') |
|
32 else: |
|
33 self.assertRaises(ValueError, float.__setformat__, |
|
34 t, 'IEEE, big-endian') |
|
35 self.assertRaises(ValueError, float.__setformat__, |
|
36 t, 'IEEE, little-endian') |
|
37 self.assertRaises(ValueError, float.__setformat__, |
|
38 t, 'chicken') |
|
39 self.assertRaises(ValueError, float.__setformat__, |
|
40 'chicken', 'unknown') |
|
41 |
|
42 BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00' |
|
43 LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF)) |
|
44 BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00' |
|
45 LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN)) |
|
46 |
|
47 BE_FLOAT_INF = '\x7f\x80\x00\x00' |
|
48 LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF)) |
|
49 BE_FLOAT_NAN = '\x7f\xc0\x00\x00' |
|
50 LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN)) |
|
51 |
|
52 # on non-IEEE platforms, attempting to unpack a bit pattern |
|
53 # representing an infinity or a NaN should raise an exception. |
|
54 |
|
55 class UnknownFormatTestCase(unittest.TestCase): |
|
56 def setUp(self): |
|
57 self.save_formats = {'double':float.__getformat__('double'), |
|
58 'float':float.__getformat__('float')} |
|
59 float.__setformat__('double', 'unknown') |
|
60 float.__setformat__('float', 'unknown') |
|
61 |
|
62 def tearDown(self): |
|
63 float.__setformat__('double', self.save_formats['double']) |
|
64 float.__setformat__('float', self.save_formats['float']) |
|
65 |
|
66 def test_double_specials_dont_unpack(self): |
|
67 for fmt, data in [('>d', BE_DOUBLE_INF), |
|
68 ('>d', BE_DOUBLE_NAN), |
|
69 ('<d', LE_DOUBLE_INF), |
|
70 ('<d', LE_DOUBLE_NAN)]: |
|
71 self.assertRaises(ValueError, struct.unpack, fmt, data) |
|
72 |
|
73 def test_float_specials_dont_unpack(self): |
|
74 for fmt, data in [('>f', BE_FLOAT_INF), |
|
75 ('>f', BE_FLOAT_NAN), |
|
76 ('<f', LE_FLOAT_INF), |
|
77 ('<f', LE_FLOAT_NAN)]: |
|
78 self.assertRaises(ValueError, struct.unpack, fmt, data) |
|
79 |
|
80 |
|
81 # on an IEEE platform, all we guarantee is that bit patterns |
|
82 # representing infinities or NaNs do not raise an exception; all else |
|
83 # is accident (today). |
|
84 |
|
85 class IEEEFormatTestCase(unittest.TestCase): |
|
86 if float.__getformat__("double").startswith("IEEE"): |
|
87 def test_double_specials_do_unpack(self): |
|
88 for fmt, data in [('>d', BE_DOUBLE_INF), |
|
89 ('>d', BE_DOUBLE_NAN), |
|
90 ('<d', LE_DOUBLE_INF), |
|
91 ('<d', LE_DOUBLE_NAN)]: |
|
92 struct.unpack(fmt, data) |
|
93 |
|
94 if float.__getformat__("float").startswith("IEEE"): |
|
95 def test_float_specials_do_unpack(self): |
|
96 for fmt, data in [('>f', BE_FLOAT_INF), |
|
97 ('>f', BE_FLOAT_NAN), |
|
98 ('<f', LE_FLOAT_INF), |
|
99 ('<f', LE_FLOAT_NAN)]: |
|
100 struct.unpack(fmt, data) |
|
101 |
|
102 if float.__getformat__("double").startswith("IEEE"): |
|
103 def test_negative_zero(self): |
|
104 import math |
|
105 def pos_pos(): |
|
106 return 0.0, math.atan2(0.0, -1) |
|
107 def pos_neg(): |
|
108 return 0.0, math.atan2(-0.0, -1) |
|
109 def neg_pos(): |
|
110 return -0.0, math.atan2(0.0, -1) |
|
111 def neg_neg(): |
|
112 return -0.0, math.atan2(-0.0, -1) |
|
113 self.assertEquals(pos_pos(), neg_pos()) |
|
114 self.assertEquals(pos_neg(), neg_neg()) |
|
115 |
|
116 def test_main(): |
|
117 test_support.run_unittest( |
|
118 FormatFunctionsTestCase, |
|
119 UnknownFormatTestCase, |
|
120 IEEEFormatTestCase) |
|
121 |
|
122 if __name__ == '__main__': |
|
123 test_main() |