2015-05-04 09:35:40 -04:00
|
|
|
try:
|
2023-08-22 11:15:46 -04:00
|
|
|
import struct
|
|
|
|
except ImportError:
|
|
|
|
print("SKIP")
|
|
|
|
raise SystemExit
|
2016-12-19 11:40:43 -05:00
|
|
|
|
2014-04-09 20:45:38 -04:00
|
|
|
print(struct.calcsize("<bI"))
|
|
|
|
print(struct.unpack("<bI", b"\x80\0\0\x01\0"))
|
2014-04-10 15:19:32 -04:00
|
|
|
print(struct.calcsize(">bI"))
|
|
|
|
print(struct.unpack(">bI", b"\x80\0\0\x01\0"))
|
2014-04-10 20:47:21 -04:00
|
|
|
|
|
|
|
# 32-bit little-endian specific
|
|
|
|
#print(struct.unpack("bI", b"\x80\xaa\x55\xaa\0\0\x01\0"))
|
2014-04-18 20:13:15 -04:00
|
|
|
|
2016-09-19 09:59:49 -04:00
|
|
|
print(struct.pack("<l", 1))
|
|
|
|
print(struct.pack(">l", 1))
|
2014-04-18 20:13:15 -04:00
|
|
|
print(struct.pack("<i", 1))
|
|
|
|
print(struct.pack(">i", 1))
|
|
|
|
print(struct.pack("<h", 1))
|
|
|
|
print(struct.pack(">h", 1))
|
|
|
|
print(struct.pack("<b", 1))
|
|
|
|
print(struct.pack(">b", 1))
|
|
|
|
|
|
|
|
print(struct.pack("<bI", -128, 256))
|
|
|
|
print(struct.pack(">bI", -128, 256))
|
2014-05-12 16:45:50 -04:00
|
|
|
|
|
|
|
print(struct.calcsize("100sI"))
|
|
|
|
print(struct.calcsize("97sI"))
|
|
|
|
print(struct.unpack("<6sH", b"foo\0\0\0\x12\x34"))
|
|
|
|
print(struct.pack("<6sH", b"foo", 10000))
|
2014-06-25 15:25:53 -04:00
|
|
|
|
|
|
|
s = struct.pack("BHBI", 10, 100, 200, 300)
|
|
|
|
v = struct.unpack("BHBI", s)
|
|
|
|
print(v == (10, 100, 200, 300))
|
2014-12-05 18:13:52 -05:00
|
|
|
|
2015-04-04 19:03:43 -04:00
|
|
|
# network byte order
|
|
|
|
print(struct.pack('!i', 123))
|
2015-09-03 18:06:18 -04:00
|
|
|
|
modstruct: Improve compliance with python3
While checking whether we can enable -Wimplicit-fallthrough, I encountered
a diagnostic in mp_binary_set_val_array_from_int which led to discovering
the following bug:
```
>>> struct.pack("xb", 3)
b'\x03\x03'
```
That is, the next value (3) was used as the value of a padding byte, while
standard Python always fills "x" bytes with zeros. I initially thought
this had to do with the unintentional fallthrough, but it doesn't.
Instead, this code would relate to an array.array with a typecode of
padding ('x'), which is ALSO not desktop Python compliant:
```
>>> array.array('x', (1, 2, 3))
array('x', [1, 0, 0])
```
Possibly this is dead code that used to be shared between struct-setting
and array-setting, but it no longer is.
I also discovered that the argument list length for struct.pack
and struct.pack_into were not checked, and that the length of binary data
passed to array.array was not checked to be a multiple of the element
size.
I have corrected all of these to conform more closely to standard Python
and revised some tests where necessary. Some tests for micropython-specific
behavior that does not conform to standard Python and is not present
in CircuitPython was deleted outright.
2020-09-12 14:57:31 -04:00
|
|
|
# too short / too long arguments
|
|
|
|
buf = bytearray(b'>>>123<<<')
|
|
|
|
try:
|
|
|
|
struct.pack_into('bb', buf, 0, 3)
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
|
|
|
|
try:
|
|
|
|
struct.pack_into('bb', buf, 0, 3, 1, 4)
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
|
|
|
|
try:
|
|
|
|
struct.pack('bb', 3)
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
|
|
|
|
try:
|
|
|
|
struct.pack('bb', 3, 1, 4)
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
|
2017-08-31 20:53:29 -04:00
|
|
|
# check that we get an error if the buffer is too small
|
|
|
|
try:
|
|
|
|
struct.unpack('I', b'\x00\x00\x00')
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
|
2015-09-03 18:06:18 -04:00
|
|
|
# first arg must be a string
|
|
|
|
try:
|
|
|
|
struct.pack(1, 2)
|
|
|
|
except TypeError:
|
|
|
|
print('TypeError')
|
2015-10-31 11:43:55 -04:00
|
|
|
|
2016-05-14 08:54:09 -04:00
|
|
|
# make sure that unknown types are detected
|
|
|
|
try:
|
|
|
|
struct.pack("z", 1)
|
|
|
|
except:
|
|
|
|
print("Unknown type")
|
|
|
|
|
2023-03-18 11:17:02 -04:00
|
|
|
# Initially repetition counters were supported only for strings,
|
2015-10-31 11:43:55 -04:00
|
|
|
# but later were implemented for all.
|
|
|
|
print(struct.unpack("<3B2h", b"foo\x12\x34\xff\xff"))
|
|
|
|
print(struct.pack("<3B", 1, 2, 3))
|
2015-12-23 22:11:27 -05:00
|
|
|
|
|
|
|
# pack_into
|
|
|
|
buf = bytearray(b'>>>123<<<')
|
|
|
|
struct.pack_into('<bbb', buf, 3, 0x41, 0x42, 0x43)
|
|
|
|
print(buf)
|
|
|
|
struct.pack_into('<bbb', buf, -6, 0x44, 0x45, 0x46)
|
|
|
|
print(buf)
|
|
|
|
|
2017-08-31 21:11:09 -04:00
|
|
|
# check that we get an error if the buffer is too small
|
|
|
|
try:
|
|
|
|
struct.pack_into('I', bytearray(1), 0, 0)
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
|
2015-12-23 22:11:27 -05:00
|
|
|
try:
|
|
|
|
struct.pack_into('<bbb', buf, 7, 0x41, 0x42, 0x43)
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
try:
|
|
|
|
struct.pack_into('<bbb', buf, -10, 0x41, 0x42, 0x43)
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
|
|
|
|
# unpack_from
|
|
|
|
buf = b'0123456789'
|
|
|
|
print(struct.unpack_from('<b', buf, 4))
|
|
|
|
print(struct.unpack_from('<b', buf, -4))
|
|
|
|
try:
|
|
|
|
print(struct.unpack_from('<b', buf, 10))
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
|
|
|
try:
|
|
|
|
print(struct.unpack_from('<b', buf, -11))
|
|
|
|
except:
|
|
|
|
print('struct.error')
|
modstruct: Improve compliance with python3
While checking whether we can enable -Wimplicit-fallthrough, I encountered
a diagnostic in mp_binary_set_val_array_from_int which led to discovering
the following bug:
```
>>> struct.pack("xb", 3)
b'\x03\x03'
```
That is, the next value (3) was used as the value of a padding byte, while
standard Python always fills "x" bytes with zeros. I initially thought
this had to do with the unintentional fallthrough, but it doesn't.
Instead, this code would relate to an array.array with a typecode of
padding ('x'), which is ALSO not desktop Python compliant:
```
>>> array.array('x', (1, 2, 3))
array('x', [1, 0, 0])
```
Possibly this is dead code that used to be shared between struct-setting
and array-setting, but it no longer is.
I also discovered that the argument list length for struct.pack
and struct.pack_into were not checked, and that the length of binary data
passed to array.array was not checked to be a multiple of the element
size.
I have corrected all of these to conform more closely to standard Python
and revised some tests where necessary. Some tests for micropython-specific
behavior that does not conform to standard Python and is not present
in CircuitPython was deleted outright.
2020-09-12 14:57:31 -04:00
|
|
|
|
|
|
|
# check padding bytes
|
|
|
|
print(struct.pack("xb", 3))
|
2021-04-16 15:39:23 -04:00
|
|
|
# Make sure pack doesn't reuse a larger value and error
|
|
|
|
print(struct.pack("xH", 0x100))
|