Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`struct.unpack_from` doesn't work with `bytearray`?

Unpacking from strings works:

>>> import struct
>>> struct.unpack('>h', 'ab')
(24930,)
>>> struct.unpack_from('>h', 'zabx', 1)
(24930,)

but if its a bytearray:

>>> struct.unpack_from('>h', bytearray('zabx'), 1)
Traceback (most recent call last):
  File "<ipython-input-4-d58338aafb82>", line 1, in <module>
    struct.unpack_from('>h', bytearray('zabx'), 1)
TypeError: unpack_from() argument 1 must be string or read-only buffer, not bytearray

Which seems a little odd. What am I actually supposed to do about it? obviously I could:

>>> struct.unpack_from('>h', str(bytearray('zabx')), 1)
(24930,)

But i'm explicitly trying to avoid copying possibly large amounts of memory around.

like image 869
SingleNegationElimination Avatar asked Mar 17 '13 22:03

SingleNegationElimination


People also ask

What does struct unpack return?

The return type of struct. unpack() is always a tuple. The function is given a format string and the binary form of data. This function is used to parse the binary form of data stored as a C structure.

How do you use structures in Python?

The module struct is used to convert the native data types of Python into string of bytes and vice versa. We don't have to install it. It's a built-in module available in Python3. The struct module is related to the C languages.


1 Answers

It looks like buffer() is the solution:

>>> struct.unpack_from('>h', buffer(bytearray('zabx')), 1)
(24930,)

buffer() is not a copy of the original, its a view:

>>> b0 = bytearray('xaby')
>>> b1 = buffer(b0)
>>> b1
<read-only buffer for ...>
>>> b1[1:3]
'ab'
>>> b0[1:3] = 'nu'
>>> b1[1:3]
'nu'

Alternitively, You(I?) can just use python 3; the limitation is lifted:

Python 3.2.3 (default, Jun  8 2012, 05:36:09) 
[GCC 4.7.0 20120507 (Red Hat 4.7.0-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import struct
>>> struct.unpack_from('>h', b'xaby', 1)
(24930,)
>>> struct.unpack_from('>h', bytearray(b'xaby'), 1)
(24930,)
>>> 
like image 106
SingleNegationElimination Avatar answered Sep 24 '22 19:09

SingleNegationElimination