Posted by Marta on March 22, 2023 Viewed 90489 times
In this article, I will explain why you will encounter the Typeerror a bytes-like object is required not ‘str’ error, and a few different ways to fix it.
The TypeError exception indicates that the operation you are trying to execute is not supported or not meant to be. You will usually get this error when you pass arguments of the wrong type. More details about the TypeError exception.
Apart from TypeError there are more exceptions in python. Check out this article to learn the most frequent exceptions and how to avoid them.
In this case, the bytes-like object is required
message indicates the operation is excepting a bytes
type; however, the type received was something else. Let’s see some examples.
This error comes up quite often when you are reading text from a file. Suppose that we have the following file, named file_sample.txt
, containing the text below:
product;stock;price bike;10;50 laptop;3;1000 microphone;5;40 book;3;9
The file contains a list of products. Each line has the product name, the current stock available, and the price. I wrote a small program that will read the file and check if there are bikes available. Here is the code:
with open('file_sample.txt', 'rb') as f: lines = [x.strip() for x in f.readlines()] bike_available = False for line in lines: tmp = line.strip().lower() split_line = tmp.split(';') if split_line[0]=='bike' and int(split_line[1])>0: bike_available = True print("Bikes Available? "+ str(bike_available))
And the output will be :
Traceback (most recent call last): Error line 7, in <module> splitted_line = tmp.split(';') TypeError: a bytes-like object is required, not 'str'
Explanation
When I opened the file, I used this: with open('file_sample.txt', 'rb')
. rb
is saying to open the file in reading binary mode. Binary mode means the data is read in the form of bytes objects. Therefore if we look at line 7, I try to split a byte object using a string. That’s why the operation results in TypeError. How can I fix this?
To fix the error, the types used by the split()
operation should match. The simplest solution is converting the delimiter to a byte object. I achieve that just by prefixing the string with a b
with open('file_sample.txt', 'rb') as f: lines = [x.strip() for x in f.readlines()] bike_available = False for line in lines: tmp = line.strip().lower() split_line = tmp.split(b';') # Added the b prefix if split_line[0]==b'bike' and int(split_line[1])>0: bike_available = True print("Bikes Available? "+ str(bike_available))
Output:
Bikes Available? True
Note I also added the b
prefix, or bytes conversion, to the condition if split_line[0]==b'bike'
, so the types also match, and the comparison is correct.
Another possible solution is opening the file in text mode. I can achieve this just by removing the b
from the open()
action. See the following code:
with open('file_sample.txt', 'r') as f: lines = [x.strip() for x in f.readlines()] bike_available = False for line in lines: tmp = line.strip().lower() split_line = tmp.split(';') if split_line[0]=='bike' and int(split_line[1])>0: bike_available = True print("Bikes Available? "+ str(bike_available))
Output:
Bikes Available? True
You could also find this error when you are trying to use the .replace()
method, and the types are not matching. Here is an example:
text_in_binary = b'Sky is blue.Roses are red' #Bytes object replaced_text = text_in_binary.replace('red','blue') print(replaced_text)
Output:
Traceback (most recent call last): File line 17, in <module> replaced_text = text_in_binary.replace('red','blue') TypeError: a bytes-like object is required, not 'str'
You can avoid this problem by making sure the types are matching. Therefore one possible solution is converting the string passed into the .replace()
function( line 2), as follows:
text_in_binary = b'Sky is blue.Roses are red' replaced_text = text_in_binary.replace(b'red',b'blue') print(replaced_text)
Output:
b'Sky is blue.Roses are blue'
Note the result is a bytes object
Another way to get the types to match is converting the byte object to a string using the .decode()
function( line 1), which will decode any binary content to string.
text= b'Sky is blue.Roses are red'.decode('utf-8') print(type(text)) replaced_text = text.replace('red','blue') print(replaced_text)
Output:
<class 'str'> Sky is blue.Roses are blue
Please note you could also save a string in the variable text
. I am using decode()
because this article aims to illustrate how to manipulate bytes objects.
You will encounter this error when you are trying to send a string via socket. The reason is the socket.send()
function expect any data to be converted to bytes. Here is a code snippet that will throw the typeerror:
import socket mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) mysock.connect(('www.py4inf.com', 80)) mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n') while True: data = mysock.recv(512) if ( len(data) < 1 ) : break print (data); mysock.close()
Output:
Traceback (most recent call last): File line 4, in <module> mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n') TypeError: a bytes-like object is required, not 'str'
To fix this, you will need to convert the http request inside the string (line 4) to bytes. There are two ways you can do this. Prefixing the string with b
, which will convert the string to bytes:
mysock.send(b'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')
or using .encode()
method to convert the string to bytes:
mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n'.encode())
The output will be the same in both cases:
b'HTTP/1.1 404 Not Found\r\nServer: nginx\r\nDate: Tue, 14 Jul 2020 10:03:11 GMT\r\nContent-Type: text/html\r\nContent-Length: 146\r\nConnection: close\r\n\r\n<html>\r\n<head><title>404 Not Found</title></head>\r\n<body>\r\n<center><h1>404 Not Found</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n'
The server response indicates the file we requested doesn’t exist. However, the code created the socket, and the HTTP request hit the destination server. Therefore we can consider the error fixed
The primary reason for this mistake is providing an incorrect data type to a function. As a result, when a function requires a bytes object as input, it’s crucial to convert the argument before passing it. This can be achieved by adding the b
prefix or by utilizing the .encode()
function.
string_var = b'Hello'.decode('utf-8') print(type(string_var))
Output:
<class 'str'>
bytes_var = 'Hello'.encode() print(type(bytes_var))
Output:
<class 'bytes'>
To summarise, when you encounter this error, it is important to double-checking the types you are used and make sure the types match, and you are not passing a wrong type to a function. I hope this helps and thanks for reading, and supporting this blog. Happy Coding!
Steady pace book with lots of worked examples. Starting with the basics, and moving to projects, data visualisation, and web applications
Unique lay-out and teaching programming style helping new concepts stick in your memory
Great guide for those who want to improve their skills when writing python code. Easy to understand. Many practical examples
Perfect Boook for anyone who has an alright knowledge of Java and wants to take it to the next level.
Excellent read for anyone who already know how to program and want to learn Best Practices
Perfect book for anyone transitioning into the mid/mid-senior developer level
Great book and probably the best way to practice for interview. Some really good information on how to perform an interview. Code Example in Java