summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/python/test/test_builtin_converters.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/python/test/test_builtin_converters.py')
-rw-r--r--src/boost/libs/python/test/test_builtin_converters.py312
1 files changed, 312 insertions, 0 deletions
diff --git a/src/boost/libs/python/test/test_builtin_converters.py b/src/boost/libs/python/test/test_builtin_converters.py
new file mode 100644
index 000000000..e612ed23d
--- /dev/null
+++ b/src/boost/libs/python/test/test_builtin_converters.py
@@ -0,0 +1,312 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+import sys
+if (sys.version_info.major >= 3):
+ long = int
+r"""
+>>> from builtin_converters_ext import *
+
+# Provide values for integer converter tests
+>>> def _signed_values(s):
+... base = 2 ** (8 * s - 1)
+... return [[-base, -1, 1, base - 1], [-base - 1, base]]
+>>> def _unsigned_values(s):
+... base = 2 ** (8 * s)
+... return [[1, base - 1], [long(-1), -1, base]]
+
+# Wrappers to simplify tests
+>>> def should_pass(method, values):
+... result = map(method, values[0])
+... if result != values[0]:
+... print("Got %s but expected %s" % (result, values[0]))
+>>> def test_overflow(method, values):
+... for v in values[1]:
+... try: method(v)
+... except OverflowError: pass
+... else: print("OverflowError expected")
+
+# Synthesize idendity functions in case long long not supported
+>>> if not 'rewrap_value_long_long' in dir():
+... def rewrap_value_long_long(x): return long(x)
+... def rewrap_value_unsigned_long_long(x): return long(x)
+... def rewrap_const_reference_long_long(x): return long(x)
+... def rewrap_const_reference_unsigned_long_long(x): return long(x)
+>>> if not 'long_long_size' in dir():
+... def long_long_size(): return long_size()
+
+>>> try: bool_exists = bool
+... except: pass
+... else:
+... rewrap_value_bool(True)
+... rewrap_value_bool(False)
+True
+False
+
+>>> rewrap_value_bool(None)
+0
+>>> rewrap_value_bool(0)
+0
+>>> rewrap_value_bool(33)
+1
+>>> rewrap_value_char('x')
+'x'
+
+ Note that there's currently silent truncation of strings passed to
+ char arguments.
+
+>>> rewrap_value_char('xy')
+'x'
+>>> rewrap_value_signed_char(42)
+42
+>>> rewrap_value_unsigned_char(42)
+42
+>>> rewrap_value_int(42)
+42
+>>> rewrap_value_unsigned_int(42)
+42
+>>> rewrap_value_short(42)
+42
+>>> rewrap_value_unsigned_short(42)
+42
+>>> rewrap_value_long(42)
+42
+>>> rewrap_value_unsigned_long(42)
+42
+
+ test unsigned long values which don't fit in a signed long.
+ strip any 'L' characters in case the platform has > 32 bit longs
+
+>>> hex(rewrap_value_unsigned_long(long(0x80000001))).replace('L','')
+'0x80000001'
+
+>>> rewrap_value_long_long(42) == 42
+True
+>>> rewrap_value_unsigned_long_long(42) == 42
+True
+
+ show that we have range checking.
+
+>>> should_pass(rewrap_value_signed_char, _signed_values(char_size()))
+>>> should_pass(rewrap_value_short, _signed_values(short_size()))
+>>> should_pass(rewrap_value_int, _signed_values(int_size()))
+>>> should_pass(rewrap_value_long, _signed_values(long_size()))
+>>> should_pass(rewrap_value_long_long, _signed_values(long_long_size()))
+
+>>> should_pass(rewrap_value_unsigned_char, _unsigned_values(char_size()))
+>>> should_pass(rewrap_value_unsigned_short, _unsigned_values(short_size()))
+>>> should_pass(rewrap_value_unsigned_int, _unsigned_values(int_size()))
+>>> should_pass(rewrap_value_unsigned_long, _unsigned_values(long_size()))
+>>> should_pass(rewrap_value_unsigned_long_long,
+... _unsigned_values(long_long_size()))
+
+>>> test_overflow(rewrap_value_signed_char, _signed_values(char_size()))
+>>> test_overflow(rewrap_value_short, _signed_values(short_size()))
+>>> test_overflow(rewrap_value_int, _signed_values(int_size()))
+>>> test_overflow(rewrap_value_long, _signed_values(long_size()))
+>>> test_overflow(rewrap_value_long_long, _signed_values(long_long_size()))
+
+>>> test_overflow(rewrap_value_unsigned_char, _unsigned_values(char_size()))
+>>> test_overflow(rewrap_value_unsigned_short, _unsigned_values(short_size()))
+>>> test_overflow(rewrap_value_unsigned_int, _unsigned_values(int_size()))
+>>> test_overflow(rewrap_value_unsigned_long, _unsigned_values(long_size()))
+
+# Exceptionally for PyLong_AsUnsignedLongLong(), a negative value raises
+# TypeError on Python versions prior to 2.7
+>>> for v in _unsigned_values(long_long_size())[1]:
+... try: rewrap_value_unsigned_long_long(v)
+... except (OverflowError, TypeError): pass
+... else: print("OverflowError or TypeError expected")
+
+>>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001
+>>> rewrap_value_double(4.2) - 4.2
+0.0
+>>> rewrap_value_long_double(4.2) - 4.2
+0.0
+
+>>> assert abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001
+>>> assert abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001
+>>> assert abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001
+
+>>> rewrap_value_cstring('hello, world')
+'hello, world'
+>>> rewrap_value_string('yo, wassup?')
+'yo, wassup?'
+
+>>> print(rewrap_value_wstring(u'yo, wassup?'))
+yo, wassup?
+
+>>> print(rewrap_value_wstring(u'\U0001f4a9'))
+\U0001f4a9
+
+ test that overloading on unicode works:
+
+>>> print(rewrap_value_string(u'yo, wassup?'))
+yo, wassup?
+
+ wrap strings with embedded nulls:
+
+>>> rewrap_value_string('yo,\0wassup?')
+'yo,\x00wassup?'
+
+>>> rewrap_value_handle(1)
+1
+>>> x = 'hi'
+>>> assert rewrap_value_handle(x) is x
+>>> assert rewrap_value_object(x) is x
+
+ Note that we can currently get a mutable pointer into an immutable
+ Python string:
+
+>>> rewrap_value_mutable_cstring('hello, world')
+'hello, world'
+
+>>> rewrap_const_reference_bool(None)
+0
+>>> rewrap_const_reference_bool(0)
+0
+
+>>> try: rewrap_const_reference_bool('yes')
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+>>> rewrap_const_reference_char('x')
+'x'
+
+ Note that there's currently silent truncation of strings passed to
+ char arguments.
+
+>>> rewrap_const_reference_char('xy')
+'x'
+>>> rewrap_const_reference_signed_char(42)
+42
+>>> rewrap_const_reference_unsigned_char(42)
+42
+>>> rewrap_const_reference_int(42)
+42
+>>> rewrap_const_reference_unsigned_int(42)
+42
+>>> rewrap_const_reference_short(42)
+42
+>>> rewrap_const_reference_unsigned_short(42)
+42
+>>> rewrap_const_reference_long(42)
+42
+>>> rewrap_const_reference_unsigned_long(42)
+42
+>>> rewrap_const_reference_long_long(42) == 42
+True
+>>> rewrap_const_reference_unsigned_long_long(42) == 42
+True
+
+
+>>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001
+>>> rewrap_const_reference_double(4.2) - 4.2
+0.0
+>>> rewrap_const_reference_long_double(4.2) - 4.2
+0.0
+
+>>> assert abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001
+>>> assert abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001
+>>> assert abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001
+
+>>> rewrap_const_reference_cstring('hello, world')
+'hello, world'
+>>> rewrap_const_reference_string('yo, wassup?')
+'yo, wassup?'
+
+>>> rewrap_const_reference_handle(1)
+1
+>>> x = 'hi'
+>>> assert rewrap_const_reference_handle(x) is x
+>>> assert rewrap_const_reference_object(x) is x
+>>> assert rewrap_reference_object(x) is x
+
+
+Check that None <==> NULL
+
+>>> rewrap_const_reference_cstring(None)
+
+But None cannot be converted to a string object:
+
+>>> try: rewrap_const_reference_string(None)
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+Now check implicit conversions between floating/integer types
+
+>>> rewrap_const_reference_float(42)
+42.0
+
+>>> rewrap_const_reference_float(long(42))
+42.0
+
+>>> try: rewrap_const_reference_int(42.0)
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+>>> rewrap_value_float(42)
+42.0
+
+>>> try: rewrap_value_int(42.0)
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+Check that classic classes also work
+
+>>> class FortyTwo:
+... def __int__(self):
+... return 42
+... def __float__(self):
+... return 42.0
+... def __complex__(self):
+... return complex(4+.2j)
+... def __str__(self):
+... return '42'
+
+>>> try: rewrap_const_reference_float(FortyTwo())
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+>>> try: rewrap_value_int(FortyTwo())
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+>>> try: rewrap_const_reference_string(FortyTwo())
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+>>> try: rewrap_value_complex_double(FortyTwo())
+... except TypeError: pass
+... else: print('expected a TypeError exception')
+
+# show that arbitrary handle<T> instantiations can be returned
+>>> assert get_type(1) is type(1)
+
+>>> assert return_null_handle() is None
+"""
+
+import sys
+if (sys.version_info.major >= 3):
+ long = int
+
+def run(args = None):
+ import sys
+ import doctest
+ import builtin_converters_ext
+
+ if 'rewrap_value_long_long' in dir(builtin_converters_ext):
+ print('LONG_LONG supported, testing...')
+ else:
+ print('LONG_LONG not supported, skipping those tests...')
+
+ if args is not None:
+ sys.argv = args
+ return doctest.testmod(sys.modules.get(__name__))
+
+if __name__ == '__main__':
+ print("running...")
+ import sys
+ status = run()[0]
+ if (status == 0): print("Done.")
+ sys.exit(status)