Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct.error: argument for 's' must be a bytes object, already supplied

I've been working on a TCP/IP connection program thingy in Python and came across the need to use Struct. And so I imported the module and after some time came to a very particular issue. I get the error specified in te title when I run the code below, which should be working after I checked some other answers and documentations.

import struct

string = "blab"

s = struct.Struct(b'4s')
packed_data = s.pack(string)

print(packed_data)

As far as I found, the issue should be fixed by prepending the string used in the s variable with 'b' or using the bytes() function parsing 'utf-8' as encoding argument. Tried both, same error.

I have no idea what might be wrong so am I missing something? I could not find relevant information online regarding this issue, so this is why I'm posting here now.

Any help is appreciated and thanks in advance!

like image 507
Smokesick Avatar asked Dec 28 '25 16:12

Smokesick


1 Answers

One problem is that you put the "b" in the wrong place. You placed it in the format string, when the data to be packed need to be a byte string.

    >>> string = "blab"
    >>> s = struct.Struct('4s')
    >>> packed_data = s.pack(string.encode('utf-8'))
    >>> print(packed_data)
    b'blab'

But even that is problematic. Suppose your string is not in the ascii character set... let's say it's Greek, then the UTF8 encoded string is more than 4 bytes and you write a truncated value

    >>> string = "ΑΒΓΔ"
    >>> s = struct.Struct('4s')
    >>> 
    >>> packed_data = s.pack(string.encode('utf-8'))
    >>> print('utf8len', len(string.encode('utf-8')), 'packedlen', len(packed_data))
    utf8len 8 packedlen 4
    >>> print(packed_data)
    b'\xce\x91\xce\x92'
    >>> print(struct.unpack('4s', packed_data)[0].decode('utf-8'))
    ΑΒ
    >>> 

If you really need to restrict to 4 bytes, then convert the original string using ascii instead of utf-8 so that any unencodable unicode character will raise an exception right away.

    >>> string = "ΑΒΓΔ"
    >>> s = struct.Struct('4s')
    >>> 
    >>> packed_data = s.pack(string.encode('ascii'))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
like image 51
tdelaney Avatar answered Dec 30 '25 06:12

tdelaney