Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / python / test / test_builtin_converters.py
1 # Copyright David Abrahams 2004. Distributed under the Boost
2 # Software License, Version 1.0. (See accompanying
3 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4 r"""
5 >>> from builtin_converters_ext import *
6
7 # Provide values for integer converter tests
8 >>> def _signed_values(s):
9 ...     base = 2 ** (8 * s - 1)
10 ...     return [[-base, -1, 1, base - 1], [-base - 1, base]]
11 >>> def _unsigned_values(s):
12 ...     base = 2 ** (8 * s)
13 ...     return [[1, base - 1], [long(-1), -1, base]]
14
15 # Wrappers to simplify tests
16 >>> def should_pass(method, values):
17 ...     result = map(method, values[0])
18 ...     if result != values[0]:
19 ...         print("Got %s but expected %s" % (result, values[0]))
20 >>> def test_overflow(method, values):
21 ...     for v in values[1]:
22 ...         try: method(v)
23 ...         except OverflowError: pass
24 ...         else: print("OverflowError expected")
25
26 # Synthesize idendity functions in case long long not supported
27 >>> if not 'rewrap_value_long_long' in dir():
28 ...     def rewrap_value_long_long(x): return long(x)
29 ...     def rewrap_value_unsigned_long_long(x): return long(x)
30 ...     def rewrap_const_reference_long_long(x): return long(x)
31 ...     def rewrap_const_reference_unsigned_long_long(x): return long(x)
32 >>> if not 'long_long_size' in dir():
33 ...     def long_long_size(): return long_size()
34
35 >>> try: bool_exists = bool
36 ... except: pass
37 ... else:
38 ...     rewrap_value_bool(True)
39 ...     rewrap_value_bool(False)
40 True
41 False
42
43 >>> rewrap_value_bool(None)
44 0
45 >>> rewrap_value_bool(0)
46 0
47 >>> rewrap_value_bool(33)
48 1
49 >>> rewrap_value_char('x')
50 'x'
51
52   Note that there's currently silent truncation of strings passed to
53   char arguments.
54
55 >>> rewrap_value_char('xy')
56 'x'
57 >>> rewrap_value_signed_char(42)
58 42
59 >>> rewrap_value_unsigned_char(42)
60 42
61 >>> rewrap_value_int(42)
62 42
63 >>> rewrap_value_unsigned_int(42)
64 42
65 >>> rewrap_value_short(42)
66 42
67 >>> rewrap_value_unsigned_short(42)
68 42
69 >>> rewrap_value_long(42)
70 42
71 >>> rewrap_value_unsigned_long(42)
72 42
73
74     test unsigned long values which don't fit in a signed long.
75     strip any 'L' characters in case the platform has > 32 bit longs
76
77 >>> hex(rewrap_value_unsigned_long(0x80000001L)).replace('L','')
78 '0x80000001'
79
80 >>> rewrap_value_long_long(42) == 42
81 True
82 >>> rewrap_value_unsigned_long_long(42) == 42
83 True
84
85    show that we have range checking.
86
87 >>> should_pass(rewrap_value_signed_char, _signed_values(char_size()))
88 >>> should_pass(rewrap_value_short, _signed_values(short_size()))
89 >>> should_pass(rewrap_value_int, _signed_values(int_size()))
90 >>> should_pass(rewrap_value_long, _signed_values(long_size()))
91 >>> should_pass(rewrap_value_long_long, _signed_values(long_long_size()))
92
93 >>> should_pass(rewrap_value_unsigned_char, _unsigned_values(char_size()))
94 >>> should_pass(rewrap_value_unsigned_short, _unsigned_values(short_size()))
95 >>> should_pass(rewrap_value_unsigned_int, _unsigned_values(int_size()))
96 >>> should_pass(rewrap_value_unsigned_long, _unsigned_values(long_size()))
97 >>> should_pass(rewrap_value_unsigned_long_long,
98 ...     _unsigned_values(long_long_size()))
99
100 >>> test_overflow(rewrap_value_signed_char, _signed_values(char_size()))
101 >>> test_overflow(rewrap_value_short, _signed_values(short_size()))
102 >>> test_overflow(rewrap_value_int, _signed_values(int_size()))
103 >>> test_overflow(rewrap_value_long, _signed_values(long_size()))
104 >>> test_overflow(rewrap_value_long_long, _signed_values(long_long_size()))
105
106 >>> test_overflow(rewrap_value_unsigned_char, _unsigned_values(char_size()))
107 >>> test_overflow(rewrap_value_unsigned_short, _unsigned_values(short_size()))
108 >>> test_overflow(rewrap_value_unsigned_int, _unsigned_values(int_size()))
109 >>> test_overflow(rewrap_value_unsigned_long, _unsigned_values(long_size()))
110
111 # Exceptionally for PyLong_AsUnsignedLongLong(), a negative value raises
112 # TypeError on Python versions prior to 2.7
113 >>> for v in _unsigned_values(long_long_size())[1]:
114 ...     try: rewrap_value_unsigned_long_long(v)
115 ...     except (OverflowError, TypeError): pass
116 ...     else: print("OverflowError or TypeError expected")
117
118 >>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001
119 >>> rewrap_value_double(4.2) - 4.2
120 0.0
121 >>> rewrap_value_long_double(4.2) - 4.2
122 0.0
123
124 >>> assert abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001
125 >>> assert abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001
126 >>> assert abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001
127
128 >>> rewrap_value_cstring('hello, world')
129 'hello, world'
130 >>> rewrap_value_string('yo, wassup?')
131 'yo, wassup?'
132
133 >>> print(rewrap_value_wstring(u'yo, wassup?'))
134 yo, wassup?
135
136 >>> print(rewrap_value_wstring(u'\U0001f4a9'))
137 \U0001f4a9
138
139    test that overloading on unicode works:
140
141 >>> print(rewrap_value_string(u'yo, wassup?'))
142 yo, wassup?
143
144    wrap strings with embedded nulls:
145
146 >>> rewrap_value_string('yo,\0wassup?')
147 'yo,\x00wassup?'
148
149 >>> rewrap_value_handle(1)
150 1
151 >>> x = 'hi'
152 >>> assert rewrap_value_handle(x) is x
153 >>> assert rewrap_value_object(x) is x
154
155   Note that we can currently get a mutable pointer into an immutable
156   Python string:
157
158 >>> rewrap_value_mutable_cstring('hello, world')
159 'hello, world'
160
161 >>> rewrap_const_reference_bool(None)
162 0
163 >>> rewrap_const_reference_bool(0)
164 0
165
166 >>> try: rewrap_const_reference_bool('yes')
167 ... except TypeError: pass
168 ... else: print('expected a TypeError exception')
169
170 >>> rewrap_const_reference_char('x')
171 'x'
172
173   Note that there's currently silent truncation of strings passed to
174   char arguments.
175
176 >>> rewrap_const_reference_char('xy')
177 'x'
178 >>> rewrap_const_reference_signed_char(42)
179 42
180 >>> rewrap_const_reference_unsigned_char(42)
181 42
182 >>> rewrap_const_reference_int(42)
183 42
184 >>> rewrap_const_reference_unsigned_int(42)
185 42
186 >>> rewrap_const_reference_short(42)
187 42
188 >>> rewrap_const_reference_unsigned_short(42)
189 42
190 >>> rewrap_const_reference_long(42)
191 42
192 >>> rewrap_const_reference_unsigned_long(42)
193 42
194 >>> rewrap_const_reference_long_long(42) == 42
195 True
196 >>> rewrap_const_reference_unsigned_long_long(42) == 42
197 True
198
199
200 >>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001
201 >>> rewrap_const_reference_double(4.2) - 4.2
202 0.0
203 >>> rewrap_const_reference_long_double(4.2) - 4.2
204 0.0
205
206 >>> assert abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001
207 >>> assert abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001
208 >>> assert abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001
209
210 >>> rewrap_const_reference_cstring('hello, world')
211 'hello, world'
212 >>> rewrap_const_reference_string('yo, wassup?')
213 'yo, wassup?'
214
215 >>> rewrap_const_reference_handle(1)
216 1
217 >>> x = 'hi'
218 >>> assert rewrap_const_reference_handle(x) is x
219 >>> assert rewrap_const_reference_object(x) is x
220 >>> assert rewrap_reference_object(x) is x
221
222
223 Check that None <==> NULL
224
225 >>> rewrap_const_reference_cstring(None)
226
227 But None cannot be converted to a string object:
228
229 >>> try: rewrap_const_reference_string(None)
230 ... except TypeError: pass
231 ... else: print('expected a TypeError exception')
232
233 Now check implicit conversions between floating/integer types
234
235 >>> rewrap_const_reference_float(42)
236 42.0
237
238 >>> rewrap_const_reference_float(long(42))
239 42.0
240
241 >>> try: rewrap_const_reference_int(42.0)
242 ... except TypeError: pass
243 ... else: print('expected a TypeError exception')
244
245 >>> rewrap_value_float(42)
246 42.0
247
248 >>> try: rewrap_value_int(42.0)
249 ... except TypeError: pass
250 ... else: print('expected a TypeError exception')
251
252 Check that classic classes also work
253
254 >>> class FortyTwo:
255 ...     def __int__(self):
256 ...         return 42
257 ...     def __float__(self):
258 ...         return 42.0
259 ...     def __complex__(self):
260 ...         return complex(4+.2j)
261 ...     def __str__(self):
262 ...         return '42'
263
264 >>> try: rewrap_const_reference_float(FortyTwo())
265 ... except TypeError: pass
266 ... else: print('expected a TypeError exception')
267
268 >>> try: rewrap_value_int(FortyTwo())
269 ... except TypeError: pass
270 ... else: print('expected a TypeError exception')
271
272 >>> try: rewrap_const_reference_string(FortyTwo())
273 ... except TypeError: pass
274 ... else: print('expected a TypeError exception')
275
276 >>> try: rewrap_value_complex_double(FortyTwo())
277 ... except TypeError: pass
278 ... else: print('expected a TypeError exception')
279
280 # show that arbitrary handle<T> instantiations can be returned
281 >>> assert get_type(1) is type(1)
282
283 >>> assert return_null_handle() is None
284 """
285
286 import sys
287 if (sys.version_info.major >= 3):
288     long = int
289
290 def run(args = None):
291     import sys
292     import doctest
293     import builtin_converters_ext
294
295     if 'rewrap_value_long_long' in dir(builtin_converters_ext):
296         print('LONG_LONG supported, testing...')
297     else:
298         print('LONG_LONG not supported, skipping those tests...')
299
300     if args is not None:
301         sys.argv = args
302     return doctest.testmod(sys.modules.get(__name__))
303
304 if __name__ == '__main__':
305     print("running...")
306     import sys
307     status = run()[0]
308     if (status == 0): print("Done.")
309     sys.exit(status)