Saman
Saman

Reputation: 177

ord() expected string of length 1, but int found

I receive a byte-array buffer from network, containing many fields. When I want to print the buffer, I get the following error:

(:ord() expected string of length 1, int found

 print(" ".join("{:02X}".format(ord(c)) for c in buf))

How can I fix this?

Upvotes: 3

Views: 15123

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121924

Python bytearray and bytes objects yield integers when iterating or indexing, not characters. Remove the ord() call:

print(" ".join("{:02X}".format(c) for c in buf))

From the Bytes documentation:

While bytes literals and representations are based on ASCII text, bytes objects actually behave like immutable sequences of integers, with each value in the sequence restricted such that 0 <= x < 256 (attempts to violate this restriction will trigger ValueError. This is done deliberately to emphasise that while many binary formats include ASCII based elements and can be usefully manipulated with some text-oriented algorithms, this is not generally the case for arbitrary binary data (blindly applying text processing algorithms to binary data formats that are not ASCII compatible will usually lead to data corruption).

and further on:

Since bytes objects are sequences of integers (akin to a tuple), for a bytes object b, b[0] will be an integer, while b[0:1] will be a bytes object of length 1. (This contrasts with text strings, where both indexing and slicing will produce a string of length 1)

I'd not use str.format() where a format() function will do; there is no larger string to interpolate the hex digits into:

print(" ".join([format(c, "02X") for c in buf]))

For str.join() calls, using list comprehension is marginally faster as the str.join() call has to convert the iterable to a list anyway; it needs to do a double scan to build the output.

Upvotes: 7

Related Questions