compatibility with PEP3118.
+--------+-------------------------+--------------------+-------+
| ``B`` | :ctype:`unsigned char` | integer | |
+--------+-------------------------+--------------------+-------+
-| ``t`` | :ctype:`_Bool` | bool | \(1) |
+| ``?`` | :ctype:`_Bool` | bool | \(1) |
+--------+-------------------------+--------------------+-------+
| ``h`` | :ctype:`short` | integer | |
+--------+-------------------------+--------------------+-------+
Notes:
(1)
- The ``'t'`` conversion code corresponds to the :ctype:`_Bool` type defined by
+ The ``'?'`` conversion code corresponds to the :ctype:`_Bool` type defined by
C99. If this type is not available, it is simulated using a :ctype:`char`. In
standard mode, it is always represented by one byte.
values, meaning a Python long integer will be used to hold the pointer; other
platforms use 32-bit pointers and will use a Python integer.
-For the ``'t'`` format character, the return value is either :const:`True` or
+For the ``'?'`` format character, the return value is either :const:`True` or
:const:`False`. When packing, the truth value of the argument object is used.
Either 0 or 1 in the native or standard bool representation will be packed, and
any non-zero value will be True when unpacking.
_check_size(c_void_p)
class c_bool(_SimpleCData):
- _type_ = "t"
+ _type_ = "?"
# This cache maps types to pointers to them.
_pointer_type_cache = {}
if sz * 3 != struct.calcsize('iii'):
raise TestFailed, 'inconsistent sizes'
-fmt = 'cbxxxxxxhhhhiillffdt'
-fmt3 = '3c3b18x12h6i6l6f3d3t'
+fmt = 'cbxxxxxxhhhhiillffd?'
+fmt3 = '3c3b18x12h6i6l6f3d3?'
sz = struct.calcsize(fmt)
sz3 = struct.calcsize(fmt3)
if sz * 3 != sz3:
t = True
for prefix in ('', '@', '<', '>', '=', '!'):
- for format in ('xcbhilfdt', 'xcBHILfdt'):
+ for format in ('xcbhilfd?', 'xcBHILfd?'):
format = prefix + format
if verbose:
print "trying:", format
('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
('d', -2.0, '\300\000\000\000\000\000\000\000',
'\000\000\000\000\000\000\000\300', 0),
- ('t', 0, '\0', '\0', 0),
- ('t', 3, '\1', '\1', 1),
- ('t', True, '\1', '\1', 0),
- ('t', [], '\0', '\0', 1),
- ('t', (1,), '\1', '\1', 1),
+ ('?', 0, '\0', '\0', 0),
+ ('?', 3, '\1', '\1', 1),
+ ('?', True, '\1', '\1', 0),
+ ('?', [], '\0', '\0', 1),
+ ('?', (1,), '\1', '\1', 1),
]
for fmt, arg, big, lil, asy in tests:
false = (), [], [], '', 0
true = [1], 'test', 5, -1, 0xffffffffL+1, 0xffffffff/2
- falseFormat = prefix + 't' * len(false)
+ falseFormat = prefix + '?' * len(false)
if verbose:
print 'trying bool pack/unpack on', false, 'using format', falseFormat
packedFalse = struct.pack(falseFormat, *false)
unpackedFalse = struct.unpack(falseFormat, packedFalse)
- trueFormat = prefix + 't' * len(true)
+ trueFormat = prefix + '?' * len(true)
if verbose:
print 'trying bool pack/unpack on', true, 'using format', trueFormat
packedTrue = struct.pack(trueFormat, *true)
raise TestFailed('%r did not unpack as false' % t)
if prefix and verbose:
- print 'trying size of bool with format %r' % (prefix+'t')
- packed = struct.pack(prefix+'t', 1)
+ print 'trying size of bool with format %r' % (prefix+'?')
+ packed = struct.pack(prefix+'?', 1)
- if len(packed) != struct.calcsize(prefix+'t'):
+ if len(packed) != struct.calcsize(prefix+'?'):
raise TestFailed('packed length is not equal to calculated size')
if len(packed) != 1 and prefix:
print 'size of bool in native format is %i' % (len(packed))
for c in '\x01\x7f\xff\x0f\xf0':
- if struct.unpack('>t', c)[0] is not True:
+ if struct.unpack('>?', c)[0] is not True:
raise TestFailed('%c did not unpack as True' % c)
test_bool()
Library
-------
+- Issue #1872: The struct module typecode for _Bool has been changed
+ from 't' to '?'.
+
- The bundled libffi copy is now in sync with the recently released
libffi3.0.4 version, apart from some small changes to
Modules/_ctypes/libffi/configure.ac.
*/
-static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOvtg";
+static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv?g";
static PyObject *
c_wchar_p_from_param(PyObject *type, PyObject *value)
/* some functions handy for testing */
+EXPORT(void)testfunc_array(int values[4])
+{
+ printf("testfunc_array %d %d %d %d\n",
+ values[0],
+ values[1],
+ values[2],
+ values[3]);
+}
+
EXPORT(long double)testfunc_Ddd(double a, double b)
{
long double result = (long double)(a * b);
#endif
static PyObject *
-t_set(void *ptr, PyObject *value, Py_ssize_t size)
+bool_set(void *ptr, PyObject *value, Py_ssize_t size)
{
switch (PyObject_IsTrue(value)) {
case -1:
}
static PyObject *
-t_get(void *ptr, Py_ssize_t size)
+bool_get(void *ptr, Py_ssize_t size)
{
return PyBool_FromLong((long)*(BOOL_TYPE *)ptr);
}
{ 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
#endif
#if SIZEOF__BOOL == 1
- { 't', t_set, t_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */
+ { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */
#elif SIZEOF__BOOL == SIZEOF_SHORT
- { 't', t_set, t_get, &ffi_type_ushort},
+ { '?', bool_set, bool_get, &ffi_type_ushort},
#elif SIZEOF__BOOL == SIZEOF_INT
- { 't', t_set, t_get, &ffi_type_uint, I_set_sw, I_get_sw},
+ { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw},
#elif SIZEOF__BOOL == SIZEOF_LONG
- { 't', t_set, t_get, &ffi_type_ulong, L_set_sw, L_get_sw},
+ { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw},
#elif SIZEOF__BOOL == SIZEOF_LONG_LONG
- { 't', t_set, t_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
+ { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
#endif /* SIZEOF__BOOL */
{ 'O', O_set, O_get, &ffi_type_pointer},
{ 0, NULL, NULL, NULL},
{'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
{'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
#endif
- {'t', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
+ {'?', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
{'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
{'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
{'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
{'L', 4, 0, bu_uint, bp_uint},
{'q', 8, 0, bu_longlong, bp_longlong},
{'Q', 8, 0, bu_ulonglong, bp_ulonglong},
- {'t', 1, 0, bu_bool, bp_bool},
+ {'?', 1, 0, bu_bool, bp_bool},
{'f', 4, 0, bu_float, bp_float},
{'d', 8, 0, bu_double, bp_double},
{0}
{'L', 4, 0, lu_uint, lp_uint},
{'q', 8, 0, lu_longlong, lp_longlong},
{'Q', 8, 0, lu_ulonglong, lp_ulonglong},
- {'t', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
+ {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
but potentially different from native rep -- reuse bx_bool funcs. */
{'f', 4, 0, lu_float, lp_float},
{'d', 8, 0, lu_double, lp_double},