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) 4import sys 5if (sys.version_info.major >= 3): 6 long = int 7r""" 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) 43True 44False 45 46>>> rewrap_value_bool(None) 470 48>>> rewrap_value_bool(0) 490 50>>> rewrap_value_bool(33) 511 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) 6142 62>>> rewrap_value_unsigned_char(42) 6342 64>>> rewrap_value_int(42) 6542 66>>> rewrap_value_unsigned_int(42) 6742 68>>> rewrap_value_short(42) 6942 70>>> rewrap_value_unsigned_short(42) 7142 72>>> rewrap_value_long(42) 7342 74>>> rewrap_value_unsigned_long(42) 7542 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(long(0x80000001))).replace('L','') 81'0x80000001' 82 83>>> rewrap_value_long_long(42) == 42 84True 85>>> rewrap_value_unsigned_long_long(42) == 42 86True 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 1230.0 124>>> rewrap_value_long_double(4.2) - 4.2 1250.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?')) 137yo, wassup? 138 139>>> print(rewrap_value_wstring(u'\U0001f4a9')) 140\U0001f4a9 141 142 test that overloading on unicode works: 143 144>>> print(rewrap_value_string(u'yo, wassup?')) 145yo, wassup? 146 147 wrap strings with embedded nulls: 148 149>>> rewrap_value_string('yo,\0wassup?') 150'yo,\x00wassup?' 151 152>>> rewrap_value_handle(1) 1531 154>>> x = 'hi' 155>>> assert rewrap_value_handle(x) is x 156>>> assert rewrap_value_object(x) is x 157 158 Note that we can currently get a mutable pointer into an immutable 159 Python string: 160 161>>> rewrap_value_mutable_cstring('hello, world') 162'hello, world' 163 164>>> rewrap_const_reference_bool(None) 1650 166>>> rewrap_const_reference_bool(0) 1670 168 169>>> try: rewrap_const_reference_bool('yes') 170... except TypeError: pass 171... else: print('expected a TypeError exception') 172 173>>> rewrap_const_reference_char('x') 174'x' 175 176 Note that there's currently silent truncation of strings passed to 177 char arguments. 178 179>>> rewrap_const_reference_char('xy') 180'x' 181>>> rewrap_const_reference_signed_char(42) 18242 183>>> rewrap_const_reference_unsigned_char(42) 18442 185>>> rewrap_const_reference_int(42) 18642 187>>> rewrap_const_reference_unsigned_int(42) 18842 189>>> rewrap_const_reference_short(42) 19042 191>>> rewrap_const_reference_unsigned_short(42) 19242 193>>> rewrap_const_reference_long(42) 19442 195>>> rewrap_const_reference_unsigned_long(42) 19642 197>>> rewrap_const_reference_long_long(42) == 42 198True 199>>> rewrap_const_reference_unsigned_long_long(42) == 42 200True 201 202 203>>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 204>>> rewrap_const_reference_double(4.2) - 4.2 2050.0 206>>> rewrap_const_reference_long_double(4.2) - 4.2 2070.0 208 209>>> assert abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001 210>>> assert abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001 211>>> assert abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001 212 213>>> rewrap_const_reference_cstring('hello, world') 214'hello, world' 215>>> rewrap_const_reference_string('yo, wassup?') 216'yo, wassup?' 217 218>>> rewrap_const_reference_handle(1) 2191 220>>> x = 'hi' 221>>> assert rewrap_const_reference_handle(x) is x 222>>> assert rewrap_const_reference_object(x) is x 223>>> assert rewrap_reference_object(x) is x 224 225 226Check that None <==> NULL 227 228>>> rewrap_const_reference_cstring(None) 229 230But None cannot be converted to a string object: 231 232>>> try: rewrap_const_reference_string(None) 233... except TypeError: pass 234... else: print('expected a TypeError exception') 235 236Now check implicit conversions between floating/integer types 237 238>>> rewrap_const_reference_float(42) 23942.0 240 241>>> rewrap_const_reference_float(long(42)) 24242.0 243 244>>> try: rewrap_const_reference_int(42.0) 245... except TypeError: pass 246... else: print('expected a TypeError exception') 247 248>>> rewrap_value_float(42) 24942.0 250 251>>> try: rewrap_value_int(42.0) 252... except TypeError: pass 253... else: print('expected a TypeError exception') 254 255Check that classic classes also work 256 257>>> class FortyTwo: 258... def __int__(self): 259... return 42 260... def __float__(self): 261... return 42.0 262... def __complex__(self): 263... return complex(4+.2j) 264... def __str__(self): 265... return '42' 266 267>>> try: rewrap_const_reference_float(FortyTwo()) 268... except TypeError: pass 269... else: print('expected a TypeError exception') 270 271>>> try: rewrap_value_int(FortyTwo()) 272... except TypeError: pass 273... else: print('expected a TypeError exception') 274 275>>> try: rewrap_const_reference_string(FortyTwo()) 276... except TypeError: pass 277... else: print('expected a TypeError exception') 278 279>>> try: rewrap_value_complex_double(FortyTwo()) 280... except TypeError: pass 281... else: print('expected a TypeError exception') 282 283# show that arbitrary handle<T> instantiations can be returned 284>>> assert get_type(1) is type(1) 285 286>>> assert return_null_handle() is None 287""" 288 289import sys 290if (sys.version_info.major >= 3): 291 long = int 292 293def run(args = None): 294 import sys 295 import doctest 296 import builtin_converters_ext 297 298 if 'rewrap_value_long_long' in dir(builtin_converters_ext): 299 print('LONG_LONG supported, testing...') 300 else: 301 print('LONG_LONG not supported, skipping those tests...') 302 303 if args is not None: 304 sys.argv = args 305 return doctest.testmod(sys.modules.get(__name__)) 306 307if __name__ == '__main__': 308 print("running...") 309 import sys 310 status = run()[0] 311 if (status == 0): print("Done.") 312 sys.exit(status) 313