does python 'replace' returns wrong error message?

Viewed 160

I just coded this:

import textract    
text = textract.process('text.pdf')
text = text.replace('\n', '<br>')
print(text)

and I got an error because process does not return a real str object.

Traceback (most recent call last):
  File "grab.py", line 4, in <module>
    text = text.replace('\n', '<br>')
TypeError: a bytes-like object is required, not 'str'

But, isn't the error message wrong? Shouldn't it say the reverse like a str object is required, not bytes ?

this is python 3.6.9

2 Answers

Both str and bytes objects have a replace method. They differ only in the type of strings they accept as parameters. In your case it appears that textract.process is returning a bytes and not a str.

>>> print(b'123'.replace(b'2', b'X'))
b'1X3'
>>> print('123'.replace('2', 'X'))
1X3
>>> print(b'123'.replace('2', 'X'))
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    print(b'123'.replace('2', 'X'))
TypeError: a bytes-like object is required, not 'str'

You can and should convert your bytes to a proper string. The way to do this is with decode, but you must know the proper encoding or you will get an error or incorrect text.

text = text.decode('utf-8')

textract returns a Python bytes object, which does have a replace method of its own. As seen in the docs, bytes.replace only accepts "bytes-like" objects. Since you supplied strings instead, it is throwing the correct TypeError.

EDIT for clarity: The replace you're wanting to do regards characters in a string (using str.replace instead). To get the desired result make sure to decode the object first:

import textract    
text = textract.process('text.pdf')
text = text.decode()
text = text.replace('\n', '<br>')
print(text)
Related