# struct.pack() raises SystemError when fed a numpy integer in some cases. # The following was run on MacOSX 10.4, little endian (I can only # reproduce the error if I specify big endian for the struct format). Not # sure if this could be a numpy bug. import struct import numpy """ in _struct.c it says /* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input numbers for explicit endians such that they fit in the given type, much like explicit casting in C. A warning will be raised if the number did not originally fit within the range of the requested type. If it is not defined, then all range errors and overflow will be struct.error exceptions. */ #define PY_STRUCT_OVERFLOW_MASKING 1 """ # a test: description, format (native, little endian, bigendian) tests = ( ('fmt_prefixs', '!', ('', '<', '>')), ('signed char', 'b', ('\x12', '\x12', '\x12')), ('unsigned char', 'B', ('\x12', '\x12', '\x12')), ('signed short', 'h', ('\x12\x00', '\x12\x00', '\x00\x12')), ('unsigned short', 'H', ('\x12\x00', '\x12\x00', '\x00\x12')), ('signed int', 'i', ('\x12\x00\x00\x00', '\x12\x00\x00\x00', '\x00\x00\x00\x12')), ('unsigned int', 'I', ('\x12\x00\x00\x00', '\x12\x00\x00\x00', '\x00\x00\x00\x12')), ('signed long', 'l', ('\x12\x00\x00\x00', '\x12\x00\x00\x00', '\x00\x00\x00\x12')), ('unsigned long', 'L', ('\x12\x00\x00\x00', '\x12\x00\x00\x00', '\x00\x00\x00\x12')), ('signed long long', 'q', ('\x12\x00\x00\x00\x00\x00\x00\x00', '\x12\x00\x00\x00\x00\x00\x00\x00', '\x00\x00\x00\x00\x00\x00\x00\x12')), ('unsigned long long', 'Q', ('\x12\x00\x00\x00\x00\x00\x00\x00', '\x12\x00\x00\x00\x00\x00\x00\x00', '\x00\x00\x00\x00\x00\x00\x00\x12')), ) for test in tests[1:]: report = "%-20s %s " % (test[0], test[1]) failures = [] for val in (numpy.int16(0x12), numpy.uint32(0x12), numpy.int64(0x12)): report += " '%s' " % repr(val.__class__).split(".")[1].split("'")[0] i = 0 for prefix in ('', '<', '>'): report += " "+prefix try: out = struct.pack(prefix+test[1], val) if test[2][i] == out: report += '.' else: report += 'f' failures.append(out) except SystemError: report += 'e' except: report += 'E' i += 1 print report, ", ".join([repr(x) for x in failures])