Mercurial > pub > dyncall > bindings
comparison python/pydc/test/types.py @ 34:2682a627168c
- breaking changes:
* restrict 'Z' conversions to immutable types
* restrict 'p' to mutable types (and handles)
author | Tassilo Philipp |
---|---|
date | Sun, 12 Apr 2020 19:37:37 +0200 |
parents | 6cc2b7fc7ea2 |
children | 0f86a5ecfe61 |
comparison
equal
deleted
inserted
replaced
33:ba47a3d709d7 | 34:2682a627168c |
---|---|
4 | 4 |
5 | 5 |
6 | 6 |
7 | 7 |
8 def theader(title): | 8 def theader(title): |
9 print(title) | 9 print("\n"+title) |
10 print('%8s %20s %16s %-20s %12s %-12s -> %16s %-16s # %s' % ('DC_SIG', 'C_RET_T', 'C_FSYM', 'C_PARAMLIST', 'PYTHON_ARG_T', 'IN_ARGS', 'RET_VAL', 'PYTHON_RET_T', 'NOTES')) | 10 print('%8s %20s %16s %-20s %11s %-16s -> %16s %-16s %12s %-16s # %s' % ('DC_SIG', 'C_RET_T', 'C_FSYM', 'C_PARAMLIST', 'PY_ARG_T', 'IN_ARGS', 'RET_VAL', 'PY_RET_T', 'OUT_ARGS', 'OUT_ARGS_T', 'NOTES')) |
11 | 11 |
12 | 12 |
13 def t(lib, dcsig, c_rtype, c_fsym, c_paramlist, extra_msg, *args): | 13 def t(lib, dcsig, c_rtype, c_fsym, c_paramlist, extra_msg, *args): |
14 # before call | |
15 inarg_types = '('+','.join(map(lambda x: type(x).__name__, args))+')' | |
16 inargs = ','.join(map(str, args)) | |
17 # call | |
14 try: | 18 try: |
15 fp = pydc.find(lib, c_fsym) | 19 fp = pydc.find(lib, c_fsym) |
16 r = pydc.call(fp, dcsig, *args) | 20 r = pydc.call(fp, dcsig, *args) |
17 rt = type(r).__name__ | 21 rt = type(r).__name__ |
18 except: | 22 except: |
19 r = '[EXCEPTION]' | 23 r = '[EXCEPTION]' |
20 rt = '!' | 24 rt = '!' |
21 extra_msg += ' "'+str(sys.exc_info()[1])+'"' | 25 e = str(sys.exc_info()[1]) |
22 | 26 extra_msg += ' "'+(e if len(e)<32 else e[0:32]+'...')+'"' |
23 inarg_types = '('+','.join(map(lambda x: type(x).__name__, args))+')' | 27 # after call |
24 inargs = ','.join(map(str, args)) | 28 outarg_types = '('+','.join(map(lambda x: type(x).__name__, args))+')' |
25 print('%8s %20s %16s %-20s %12s %-12s -> %16.16s %-16s # %s' % (dcsig, c_rtype, c_fsym, c_paramlist, inarg_types, inargs, str(r), '('+rt+')', extra_msg)) | 29 outargs = ','.join(map(str, args)) |
30 print('%8s %20s %16s %-20s %11s \033[33m%-16s\033[0m -> \033[32m%16.16s\033[0m %-16s %12s \033[32m%-16s\033[0m # %s' % (dcsig, c_rtype, c_fsym, c_paramlist, inarg_types, inargs, str(r), '('+rt+')', outarg_types, outargs, extra_msg)) | |
26 | 31 |
27 | 32 |
28 | 33 |
29 # some libc tests ------------------ | 34 # some libc tests ------------------ |
30 | 35 |
82 | 87 |
83 # tests with own .so for testing all conversions ------------------ | 88 # tests with own .so for testing all conversions ------------------ |
84 | 89 |
85 l = pydc.load(sys.path[0]+"/test.so") | 90 l = pydc.load(sys.path[0]+"/test.so") |
86 | 91 |
92 # "long" typed test value use for Python 2 | |
93 long_i = 11234 | |
94 long_h = 0xdeadc0de | |
95 if sys.version_info < (3, 0): | |
96 long_i = long(11234) | |
97 long_h = long(0xdeadc0de) | |
98 | |
87 # test all possible arg types and their conversions to and from python, with | 99 # test all possible arg types and their conversions to and from python, with |
88 # specific focus/tests in areas where python 2 and 3 differ | 100 # specific focus/tests in areas where python 2 and 3 differ |
89 theader('ARG & RET TYPE CONVERSION TESTS:') | 101 theader('ARG & RET TYPE CONVERSION TESTS:') |
90 t(l, "B)B", "int", "i_plus_one", "(int)", ' False => True (using int func in C)', False) | 102 t(l, "B)B", "int", "i_plus_one", "(int)", ' False => True (using int func in C)', False) |
103 | |
91 t(l, "c)c", "char", "c_plus_one", "(char)", ' "a" (97) => 98', 'a') | 104 t(l, "c)c", "char", "c_plus_one", "(char)", ' "a" (97) => 98', 'a') |
92 t(l, "C)C", "unsigned char", "uc_plus_one", "(unsigned char)", ' "a" (97) => 98', 'a') | 105 t(l, "C)C", "unsigned char", "uc_plus_one", "(unsigned char)", ' "a" (97) => 98', 'a') |
93 t(l, "c)c", "char", "c_plus_one", "(char)", ' -2 => -1', -2) | 106 t(l, "c)c", "char", "c_plus_one", "(char)", ' -2 => -1', -2) |
94 t(l, "C)C", "unsigned char", "uc_plus_one", "(unsigned char)", ' 10 => 11', 10) | 107 t(l, "C)C", "unsigned char", "uc_plus_one", "(unsigned char)", ' 10 => 11', 10) |
108 | |
95 t(l, "s)s", "short", "s_plus_one", "(short)", ' 10 => 11', 10) | 109 t(l, "s)s", "short", "s_plus_one", "(short)", ' 10 => 11', 10) |
96 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 10 => 11', 10) | 110 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 10 => 11', 10) |
111 | |
97 t(l, "i)i", "int", "i_plus_one", "(int)", ' 10 => 11', 10) | 112 t(l, "i)i", "int", "i_plus_one", "(int)", ' 10 => 11', 10) |
98 t(l, "I)I", "unsigned int", "ui_plus_one", "(unsigned int)", ' 10 => 11', 10) | 113 t(l, "I)I", "unsigned int", "ui_plus_one", "(unsigned int)", ' 10 => 11', 10) |
114 | |
99 t(l, "j)j", "long", "l_plus_one", "(long)", ' 10 => 11', 10) | 115 t(l, "j)j", "long", "l_plus_one", "(long)", ' 10 => 11', 10) |
100 t(l, "J)J", "unsigned long", "ul_plus_one", "(unsigned long)", ' 10 => 11', 10) | 116 t(l, "J)J", "unsigned long", "ul_plus_one", "(unsigned long)", ' 10 => 11', 10) |
117 | |
101 t(l, "l)l", "long long", "ll_plus_one", "(long long)", ' 10 => 11', 10) | 118 t(l, "l)l", "long long", "ll_plus_one", "(long long)", ' 10 => 11', 10) |
102 t(l, "L)L", "unsigned long long", "ull_plus_one", "(unsigned long long)", ' 10 => 11', 10) | 119 t(l, "L)L", "unsigned long long", "ull_plus_one", "(unsigned long long)", ' 10 => 11', 10) |
120 t(l, "l)l", "long long", "ll_plus_one", "(long long)", ' 11234 => 11235', long_i) | |
121 t(l, "L)L", "unsigned long long", "ull_plus_one", "(unsigned long long)", ' 11234 => 11235', long_i) | |
122 | |
103 t(l, "f)f", "float", "f_plus_one", "(float)", ' -1.23 => -0.23', -1.23) | 123 t(l, "f)f", "float", "f_plus_one", "(float)", ' -1.23 => -0.23', -1.23) |
104 t(l, "d)d", "double", "d_plus_one", "(double)", ' 5.67 => 6.67', 5.67) | 124 t(l, "d)d", "double", "d_plus_one", "(double)", ' 5.67 => 6.67', 5.67) |
105 t(l, "Z)Z", "const char*", "cc_plus_one", "(const char*)", '"lose char" => "ose char"', 'lose char') | 125 |
106 t(l, "p)Z", "const char*", "cc_plus_one", "(const char*)", '"w/pointer" => "/pointer"', 'w/pointer') | 126 t(l, "Z)Z", "const char*", "ccp_plus_one", "(const char*)", '"lose char" => "ose char"', 'lose char') # string object |
107 t(l, "p)p", "const char*", "cc_plus_one", "(const char*)", ' "x" => p+1 (retval is prob odd addr)', 'x') | 127 t(l, "Z)Z", "const char*", "ccp_plus_one", "(const char*)", '"X_unicode" => "_unicode"', u'X_unicode') # string object (unicode in Python 2) |
108 t(l, "p)p", "const char*", "cc_plus_one", "(const char*)", ' 0xdeadc0de => 0xdeadc0de+1=3735929055',0xdeadc0de) | 128 t(l, "Z)Z", "const char*", "ccp_plus_one", "(const char*)", '"1lessbyte" => "lessbyte"', b'1lessbyte') # bytes object |
129 t(l, "Z)Z", "const char*", "ccp_plus_one", "(const char*)", ' "xY" => "Y"', bytearray(b'xY')) # bytearray object | |
130 | |
131 t(l, "p)Z", "const char*", "ccp_plus_one", "(const char*)", ' "xY" => "Y"', bytearray(b'xY')) # bytearray object | |
132 t(l, "p)p", "const char*", "ccp_plus_one", "(const char*)", ' "xY" => p+1 (~ odd addr)', bytearray(b'xY')) # bytearray object | |
133 t(l, "p)p", "const char*", "ccp_plus_one", "(const char*)", ' 0xdeadc0de => 0xdeadc0de+1=3735929055', long_h) # handle (integer interpreted as ptr) | |
134 t(l, "p)p", "const char*", "ccp_plus_one", "(const char*)", ' 0xdeadc0de => 0xdeadc0de+1=3735929055', long_h) # handle (integer interpreted as ptr, long in Python 2) | |
135 | |
136 # functions that change buffers | |
137 theader('TESTS OF IMMUTABLE AND MUTABLE PYTHON BUFFERS:') | |
138 t(l, "Z)v", "const char*", "cp_head_incr", "(const char*)", ' "string" => None / arg => "string" (not modified)"', 'string') # string object | |
139 t(l, "Z)v", "const char*", "cp_head_incr", "(const char*)", ' "UnIcOdE" => None / arg => "UnIcOdE" (not modified)"', u'UnIcOdE') # string object (unicode in Python 2) | |
140 t(l, "Z)v", "const char*", "cp_head_incr", "(const char*)", ' "BCssk#" => None / arg => "BCssk#" (not modified)"', b'BCssk#') # bytes object | |
141 t(l, "Z)v", "const char*", "cp_head_incr", "(const char*)", ' "xY" => None / arg => "xY" (not modified)"', bytearray(b'xY')) # bytearray object | |
142 t(l, "p)v", "const char*", "cp_head_incr", "(const char*)", ' "xY" => None / arg => "yY" (!MODIFIED!)"', bytearray(b'xY')) # bytearray object | |
109 | 143 |
110 # tested checked value conversions | 144 # tested checked value conversions |
111 theader('ARG & RET TYPE CONVERSION TESTS FOR RANGE CHECKED TYPES:') | 145 theader('ARG & RET TYPE CONVERSION TESTS FOR RANGE CHECKED TYPES:') |
112 t(l, "c)c", "char", "c_plus_one", "(char)", ' "~" => 127', '~') | 146 t(l, "c)c", "char", "c_plus_one", "(char)", ' "~" => 127', '~') |
113 t(l, "c)c", "char", "c_plus_one", "(char)", ' "~" => 127', '~') | 147 t(l, "c)c", "char", "c_plus_one", "(char)", ' "~" => 127', '~') |
134 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 0 => 1', 0) | 168 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 0 => 1', 0) |
135 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 65535 => 0 (wrapped)', 65535) | 169 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 65535 => 0 (wrapped)', 65535) |
136 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' -1 => input exc:', -1) | 170 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' -1 => input exc:', -1) |
137 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 65536 => input exc:', 65536) | 171 t(l, "S)S", "unsigned short", "us_plus_one", "(unsigned short)", ' 65536 => input exc:', 65536) |
138 | 172 |
173 t(l, "p)Z", "const char*", "ccp_plus_one", "(const char*)", '"w/pointer" => input exc:', 'w/pointer') # string object, not passable as 'p'ointer | |
174 t(l, "p)Z", "const char*", "ccp_plus_one", "(const char*)", '"X_unicode" => input exc:',u'X_unicode') # string object (unicode in Python 2), not passable as 'p'ointer | |
175 t(l, "p)Z", "const char*", "ccp_plus_one", "(const char*)", '"1less/ptr" => input exc:',b'1less/ptr') # bytes object, not passable as 'p'ointer | |
176 t(l, "p)p", "const char*", "ccp_plus_one", "(const char*)", ' "x" => input exc:', 'x') # string object, not passable as 'p'ointer | |
139 | 177 |
140 # int | |
141 # rand(void); | |
142 #rand() | |
143 #define DC_SIGCHAR_VOID 'v' ra | |
144 #define DC_SIGCHAR_BOOL 'B' | |
145 #define DC_SIGCHAR_CHAR 'c' 2 versions | |
146 #define DC_SIGCHAR_UCHAR 'C' | |
147 #define DC_SIGCHAR_SHORT 's' | |
148 #define DC_SIGCHAR_USHORT 'S' | |
149 #define DC_SIGCHAR_INT 'i' r | |
150 #define DC_SIGCHAR_UINT 'I' a | |
151 #define DC_SIGCHAR_LONG 'j' ra | |
152 #define DC_SIGCHAR_ULONG 'J' | |
153 #define DC_SIGCHAR_LONGLONG 'l' ra | |
154 #define DC_SIGCHAR_ULONGLONG 'L' | |
155 #define DC_SIGCHAR_FLOAT 'f' | |
156 #define DC_SIGCHAR_DOUBLE 'd' | |
157 #define DC_SIGCHAR_POINTER 'p' | |
158 #define DC_SIGCHAR_STRING 'Z' | |
159 #define DC_SIGCHAR_STRUCT 'T' | |
160 #define DC_SIGCHAR_ENDARG ')' /* also works for end struct */ | |
161 | |
162 | |
163 | |
164 # SIG | FROM PYTHON 2 | FROM PYTHON 3 @@@ | C/C++ | TO PYTHON 2 | TO PYTHON 3 @@@ | |
165 # ----+------------------------------------+------------------------------------+---------------------------------+------------------------------------+----------------------------------- | |
166 # 'v' | | | void | ?NoneType (returned for "xxx)v") | NoneType (returned for "xxx)v") | |
167 # 'B' | ?PyBool | ?PyBool | bool | ?PyBool | ?PyBool | |
168 # 'c' | ?PyInt (range checked) | ?PyLong (range checked) | char | ?PyInt | ?PyLong | |
169 # 'C' | ?PyInt (range checked) | ?PyLong (range checked) | unsigned char | ?PyInt | ?PyLong | |
170 # 's' | ?PyInt (range checked) | ?PyLong (range checked) | short | ?PyInt | ?PyLong | |
171 # 'S' | ?PyInt (range checked) | ?PyLong (range checked) | unsigned short | ?PyInt | ?PyLong | |
172 # 'i' | ?PyInt | ?PyLong | int | ?PyInt | ?PyLong | |
173 # 'I' | ?PyInt | ?PyLong | unsigned int | ?PyInt | ?PyLong | |
174 # 'j' | ?PyLong | ?PyLong | long | ?PyLong | ?PyLong | |
175 # 'J' | ?PyLong | ?PyLong | unsigned long | ?PyLong | ?PyLong | |
176 # 'l' | ?PyLongLong | ?PyLongLong | long long | ?PyLongLong | ?PyLongLong | |
177 # 'L' | ?PyLongLong | ?PyLongLong | unsigned long long | ?PyLongLong | ?PyLongLong | |
178 # 'f' | ?PyFloat (cast to single precision) | ?PyFloat (cast to single precision) | float | ?PyFloat (cast to double precision) | ?PyFloat (cast to double precision) | |
179 # 'd' | ?PyFloat | ?PyFloat | double | ?PyFloat | ?PyFloat | |
180 # 'p' | ?PyUnicode/PyString/PyLong | ?PyUnicode/PyBytes/PyLong | void* | ?Py_ssize_t | ?Py_ssize_t | |
181 # 'Z' | ?PyUnicode/PyString | ?PyUnicode/PyBytes | const char* (UTF-8 for unicode) | ?PyString | ?PyUnicode | |
182 |