]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | import sys | |
5 | if (sys.version_info.major >= 3): | |
6 | long = int | |
7 | r""" | |
8 | >>> from builtin_converters_ext import * | |
9 | ||
10 | # Provide values for integer converter tests | |
11 | >>> def _signed_values(s): | |
12 | ... base = 2 ** (8 * s - 1) | |
13 | ... return [[-base, -1, 1, base - 1], [-base - 1, base]] | |
14 | >>> def _unsigned_values(s): | |
15 | ... base = 2 ** (8 * s) | |
16 | ... return [[1, base - 1], [long(-1), -1, base]] | |
17 | ||
18 | # Wrappers to simplify tests | |
19 | >>> def should_pass(method, values): | |
20 | ... result = map(method, values[0]) | |
21 | ... if result != values[0]: | |
22 | ... print("Got %s but expected %s" % (result, values[0])) | |
23 | >>> def test_overflow(method, values): | |
24 | ... for v in values[1]: | |
25 | ... try: method(v) | |
26 | ... except OverflowError: pass | |
27 | ... else: print("OverflowError expected") | |
28 | ||
29 | # Synthesize idendity functions in case long long not supported | |
30 | >>> if not 'rewrap_value_long_long' in dir(): | |
31 | ... def rewrap_value_long_long(x): return long(x) | |
32 | ... def rewrap_value_unsigned_long_long(x): return long(x) | |
33 | ... def rewrap_const_reference_long_long(x): return long(x) | |
34 | ... def rewrap_const_reference_unsigned_long_long(x): return long(x) | |
35 | >>> if not 'long_long_size' in dir(): | |
36 | ... def long_long_size(): return long_size() | |
37 | ||
38 | >>> try: bool_exists = bool | |
39 | ... except: pass | |
40 | ... else: | |
41 | ... rewrap_value_bool(True) | |
42 | ... rewrap_value_bool(False) | |
43 | True | |
44 | False | |
45 | ||
46 | >>> rewrap_value_bool(None) | |
47 | 0 | |
48 | >>> rewrap_value_bool(0) | |
49 | 0 | |
50 | >>> rewrap_value_bool(33) | |
51 | 1 | |
52 | >>> rewrap_value_char('x') | |
53 | 'x' | |
54 | ||
55 | Note that there's currently silent truncation of strings passed to | |
56 | char arguments. | |
57 | ||
58 | >>> rewrap_value_char('xy') | |
59 | 'x' | |
60 | >>> rewrap_value_signed_char(42) | |
61 | 42 | |
62 | >>> rewrap_value_unsigned_char(42) | |
63 | 42 | |
64 | >>> rewrap_value_int(42) | |
65 | 42 | |
66 | >>> rewrap_value_unsigned_int(42) | |
67 | 42 | |
68 | >>> rewrap_value_short(42) | |
69 | 42 | |
70 | >>> rewrap_value_unsigned_short(42) | |
71 | 42 | |
72 | >>> rewrap_value_long(42) | |
73 | 42 | |
74 | >>> rewrap_value_unsigned_long(42) | |
75 | 42 | |
76 | ||
77 | test unsigned long values which don't fit in a signed long. | |
78 | strip any 'L' characters in case the platform has > 32 bit longs | |
79 | ||
80 | >>> hex(rewrap_value_unsigned_long(0x80000001L)).replace('L','') | |
81 | '0x80000001' | |
82 | ||
83 | >>> rewrap_value_long_long(42) == 42 | |
84 | True | |
85 | >>> rewrap_value_unsigned_long_long(42) == 42 | |
86 | True | |
87 | ||
88 | show that we have range checking. | |
89 | ||
90 | >>> should_pass(rewrap_value_signed_char, _signed_values(char_size())) | |
91 | >>> should_pass(rewrap_value_short, _signed_values(short_size())) | |
92 | >>> should_pass(rewrap_value_int, _signed_values(int_size())) | |
93 | >>> should_pass(rewrap_value_long, _signed_values(long_size())) | |
94 | >>> should_pass(rewrap_value_long_long, _signed_values(long_long_size())) | |
95 | ||
96 | >>> should_pass(rewrap_value_unsigned_char, _unsigned_values(char_size())) | |
97 | >>> should_pass(rewrap_value_unsigned_short, _unsigned_values(short_size())) | |
98 | >>> should_pass(rewrap_value_unsigned_int, _unsigned_values(int_size())) | |
99 | >>> should_pass(rewrap_value_unsigned_long, _unsigned_values(long_size())) | |
100 | >>> should_pass(rewrap_value_unsigned_long_long, | |
101 | ... _unsigned_values(long_long_size())) | |
102 | ||
103 | >>> test_overflow(rewrap_value_signed_char, _signed_values(char_size())) | |
104 | >>> test_overflow(rewrap_value_short, _signed_values(short_size())) | |
105 | >>> test_overflow(rewrap_value_int, _signed_values(int_size())) | |
106 | >>> test_overflow(rewrap_value_long, _signed_values(long_size())) | |
107 | >>> test_overflow(rewrap_value_long_long, _signed_values(long_long_size())) | |
108 | ||
109 | >>> test_overflow(rewrap_value_unsigned_char, _unsigned_values(char_size())) | |
110 | >>> test_overflow(rewrap_value_unsigned_short, _unsigned_values(short_size())) | |
111 | >>> test_overflow(rewrap_value_unsigned_int, _unsigned_values(int_size())) | |
112 | >>> test_overflow(rewrap_value_unsigned_long, _unsigned_values(long_size())) | |
113 | ||
114 | # Exceptionally for PyLong_AsUnsignedLongLong(), a negative value raises | |
115 | # TypeError on Python versions prior to 2.7 | |
116 | >>> for v in _unsigned_values(long_long_size())[1]: | |
117 | ... try: rewrap_value_unsigned_long_long(v) | |
118 | ... except (OverflowError, TypeError): pass | |
119 | ... else: print("OverflowError or TypeError expected") | |
120 | ||
121 | >>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001 | |
122 | >>> rewrap_value_double(4.2) - 4.2 | |
123 | 0.0 | |
124 | >>> rewrap_value_long_double(4.2) - 4.2 | |
125 | 0.0 | |
126 | ||
127 | >>> assert abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001 | |
128 | >>> assert abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001 | |
129 | >>> assert abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001 | |
130 | ||
131 | >>> rewrap_value_cstring('hello, world') | |
132 | 'hello, world' | |
133 | >>> rewrap_value_string('yo, wassup?') | |
134 | 'yo, wassup?' | |
135 | ||
136 | >>> print(rewrap_value_wstring(u'yo, wassup?')) | |
137 | yo, wassup? | |
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 | def run(args = None): | |
287 | import sys | |
288 | import doctest | |
289 | import builtin_converters_ext | |
290 | ||
291 | if 'rewrap_value_long_long' in dir(builtin_converters_ext): | |
292 | print('LONG_LONG supported, testing...') | |
293 | else: | |
294 | print('LONG_LONG not supported, skipping those tests...') | |
295 | ||
296 | if args is not None: | |
297 | sys.argv = args | |
298 | return doctest.testmod(sys.modules.get(__name__)) | |
299 | ||
300 | if __name__ == '__main__': | |
301 | print("running...") | |
302 | import sys | |
303 | status = run()[0] | |
304 | if (status == 0): print("Done.") | |
305 | sys.exit(status) |