'str' object has no attribute 'decode'. Python 3 error?
Question:
Here is my code:
import imaplib
from email.parser import HeaderParser
conn = imaplib.IMAP4_SSL('imap.gmail.com')
conn.login('[email protected]', 'password')
conn.select()
conn.search(None, 'ALL')
data = conn.fetch('1', '(BODY[HEADER])')
header_data = data[1][0][1].decode('utf-8')
At this point I get the error message:
AttributeError: ‘str’ object has no attribute ‘decode’
Python 3 doesn’t have str.decode() anymore, so how can I fix this?
Answers:
You are trying to decode an object that is already decoded. You have a str
, there is no need to decode from UTF-8 anymore.
Simply drop the .decode('utf-8')
part:
header_data = data[1][0][1]
Begining with Python 3, all strings are unicode objects.
a = 'Happy New Year' # Python 3
b = unicode('Happy New Year') # Python 2
The instructions above are the same. So I think you should remove the .decode('utf-8')
part because you already have a unicode object.
Use it by this Method:
str.encode().decode()
I’m not familiar with the library, but if your problem is that you don’t want a byte array, one easy way is to specify an encoding type straight in a cast:
>>> my_byte_str
b'Hello World'
>>> str(my_byte_str, 'utf-8')
'Hello World'
It s already decoded in Python3, Try directly it should work.
For Python3
html = """\u003Cdiv id=\u0022contenedor\u0022\u003E \u003Ch2 class=\u0022text-left m-b-2\u0022\u003EInformaci\u00f3n del veh\u00edculo de patente AA345AA\u003C\/h2\u003E\n\n\n\n \u003Cdiv class=\u0022panel panel-default panel-disabled m-b-2\u0022\u003E\n \u003Cdiv class=\u0022panel-body\u0022\u003E\n \u003Ch2 class=\u0022table_title m-b-2\u0022\u003EInformaci\u00f3n del Registro Automotor\u003C\/h2\u003E\n \u003Cdiv class=\u0022col-md-6\u0022\u003E\n \u003Clabel class=\u0022control-label\u0022\u003ERegistro Seccional\u003C\/label\u003E\n \u003Cp\u003ESAN MIGUEL N\u00b0 1\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EDirecci\u00f3n\u003C\/label\u003E\n \u003Cp\u003EMAESTRO ANGEL D\u0027ELIA 766\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EPiso\u003C\/label\u003E\n \u003Cp\u003EPB\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EDepartamento\u003C\/label\u003E\n \u003Cp\u003E-\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EC\u00f3digo postal\u003C\/label\u003E\n \u003Cp\u003E1663\u003C\/p\u003E\n \u003C\/div\u003E\n \u003Cdiv class=\u0022col-md-6\u0022\u003E\n \u003Clabel class=\u0022control-label\u0022\u003ELocalidad\u003C\/label\u003E\n \u003Cp\u003ESAN MIGUEL\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EProvincia\u003C\/label\u003E\n \u003Cp\u003EBUENOS AIRES\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003ETel\u00e9fono\u003C\/label\u003E\n \u003Cp\u003E(11)46646647\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EHorario\u003C\/label\u003E\n \u003Cp\u003E08:30 a 12:30\u003C\/p\u003E\n \u003C\/div\u003E\n \u003C\/div\u003E\n\u003C\/div\u003E \n\n\u003Cp class=\u0022text-center m-t-3 m-b-1 hidden-print\u0022\u003E\n \u003Ca href=\u0022javascript:window.print();\u0022 class=\u0022btn btn-default\u0022\u003EImprim\u00ed la consulta\u003C\/a\u003E \u0026nbsp; \u0026nbsp;\n \u003Ca href=\u0022\u0022 class=\u0022btn use-ajax btn-primary\u0022\u003EHacer otra consulta\u003C\/a\u003E\n\u003C\/p\u003E\n\u003C\/div\u003E"""
print(html.replace("\/", "/").encode().decode('unicode_escape'))
Other answers sort of hint at it, but the problem may arise from expecting a bytes object. In Python 3, decode is valid when you have an object of class bytes. Running encode before decode may “fix” the problem, but it is a useless pair of operations that suggest the problem us upstream.
Use codecs module’s open() to read file:
import codecs
with codecs.open(file_name, 'r', encoding='utf-8', errors='ignore') as fdata:
This worked for me:
html.replace("\/", "/").encode().decode('unicode_escape', 'surrogatepass')
This is similar to json.loads(html) behaviour
If you land here using jwt authentication after the PyJWT v2.0.0 release (22/12/2020), you might want to freeze your version of PyJWT to the previous release in your requirements.txt
file.
PyJWT==1.7.1
I got ‘str’ object has no attribute ‘decode’ while creating JWT access_token
using Flask_JWT_extended
package.
To fix this issue, I upgraded my Flask-JWT-Extended
package to Flask-JWT-Extended==4.1.0
For Reference:
Please Visit this page: https://flask-jwt-extended.readthedocs.io/en/stable/
In Python 3, this mental model is pretty straight-forward:
- Encoding is the process of converting a
str
to a bytes
object
- Decoding is the process of converting a
bytes
object to a str
┏━━━━━━━┓ ┏━━━━━━━┓
┃ ┃ -> encoding -> ┃ ┃
┃ str ┃ ┃ bytes ┃
┃ ┃ <- decoding <- ┃ ┃
┗━━━━━━━┛ ┗━━━━━━━┛
In your case, you are calling data.decode("UTF-8")
, but the variable is already a str
object and is already decoded. So just refer to data
directly if a string is what you need.
If anyone getting the same error while participating in Kaggle for a Logistic REgre, here is the solution :
logmodel = LogisticRegression(solver='liblinear')
If you are working with Django and simple-jwt:
Here is your 100% solution
pip install PyJWT==1.7.1
my case may have been a bit rare but I was working with django and my project was running locally but not when I deployed it, it seemed as though I was getting multiple dependency errors because I was doing: pip freeze > requirements.txt
doing this fixed the issue:
pip3 freeze > requirements.txt
First install suitable JWT
pip3 install PyJWT
then in your code
token.encode().decode('UTF-8')
this worked me, I think this will help you
Here is my code:
import imaplib
from email.parser import HeaderParser
conn = imaplib.IMAP4_SSL('imap.gmail.com')
conn.login('[email protected]', 'password')
conn.select()
conn.search(None, 'ALL')
data = conn.fetch('1', '(BODY[HEADER])')
header_data = data[1][0][1].decode('utf-8')
At this point I get the error message:
AttributeError: ‘str’ object has no attribute ‘decode’
Python 3 doesn’t have str.decode() anymore, so how can I fix this?
You are trying to decode an object that is already decoded. You have a str
, there is no need to decode from UTF-8 anymore.
Simply drop the .decode('utf-8')
part:
header_data = data[1][0][1]
Begining with Python 3, all strings are unicode objects.
a = 'Happy New Year' # Python 3
b = unicode('Happy New Year') # Python 2
The instructions above are the same. So I think you should remove the .decode('utf-8')
part because you already have a unicode object.
Use it by this Method:
str.encode().decode()
I’m not familiar with the library, but if your problem is that you don’t want a byte array, one easy way is to specify an encoding type straight in a cast:
>>> my_byte_str
b'Hello World'
>>> str(my_byte_str, 'utf-8')
'Hello World'
It s already decoded in Python3, Try directly it should work.
For Python3
html = """\u003Cdiv id=\u0022contenedor\u0022\u003E \u003Ch2 class=\u0022text-left m-b-2\u0022\u003EInformaci\u00f3n del veh\u00edculo de patente AA345AA\u003C\/h2\u003E\n\n\n\n \u003Cdiv class=\u0022panel panel-default panel-disabled m-b-2\u0022\u003E\n \u003Cdiv class=\u0022panel-body\u0022\u003E\n \u003Ch2 class=\u0022table_title m-b-2\u0022\u003EInformaci\u00f3n del Registro Automotor\u003C\/h2\u003E\n \u003Cdiv class=\u0022col-md-6\u0022\u003E\n \u003Clabel class=\u0022control-label\u0022\u003ERegistro Seccional\u003C\/label\u003E\n \u003Cp\u003ESAN MIGUEL N\u00b0 1\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EDirecci\u00f3n\u003C\/label\u003E\n \u003Cp\u003EMAESTRO ANGEL D\u0027ELIA 766\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EPiso\u003C\/label\u003E\n \u003Cp\u003EPB\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EDepartamento\u003C\/label\u003E\n \u003Cp\u003E-\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EC\u00f3digo postal\u003C\/label\u003E\n \u003Cp\u003E1663\u003C\/p\u003E\n \u003C\/div\u003E\n \u003Cdiv class=\u0022col-md-6\u0022\u003E\n \u003Clabel class=\u0022control-label\u0022\u003ELocalidad\u003C\/label\u003E\n \u003Cp\u003ESAN MIGUEL\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EProvincia\u003C\/label\u003E\n \u003Cp\u003EBUENOS AIRES\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003ETel\u00e9fono\u003C\/label\u003E\n \u003Cp\u003E(11)46646647\u003C\/p\u003E\n \u003Clabel class=\u0022control-label\u0022\u003EHorario\u003C\/label\u003E\n \u003Cp\u003E08:30 a 12:30\u003C\/p\u003E\n \u003C\/div\u003E\n \u003C\/div\u003E\n\u003C\/div\u003E \n\n\u003Cp class=\u0022text-center m-t-3 m-b-1 hidden-print\u0022\u003E\n \u003Ca href=\u0022javascript:window.print();\u0022 class=\u0022btn btn-default\u0022\u003EImprim\u00ed la consulta\u003C\/a\u003E \u0026nbsp; \u0026nbsp;\n \u003Ca href=\u0022\u0022 class=\u0022btn use-ajax btn-primary\u0022\u003EHacer otra consulta\u003C\/a\u003E\n\u003C\/p\u003E\n\u003C\/div\u003E"""
print(html.replace("\/", "/").encode().decode('unicode_escape'))
Other answers sort of hint at it, but the problem may arise from expecting a bytes object. In Python 3, decode is valid when you have an object of class bytes. Running encode before decode may “fix” the problem, but it is a useless pair of operations that suggest the problem us upstream.
Use codecs module’s open() to read file:
import codecs
with codecs.open(file_name, 'r', encoding='utf-8', errors='ignore') as fdata:
This worked for me:
html.replace("\/", "/").encode().decode('unicode_escape', 'surrogatepass')
This is similar to json.loads(html) behaviour
If you land here using jwt authentication after the PyJWT v2.0.0 release (22/12/2020), you might want to freeze your version of PyJWT to the previous release in your requirements.txt
file.
PyJWT==1.7.1
I got ‘str’ object has no attribute ‘decode’ while creating JWT access_token
using Flask_JWT_extended
package.
To fix this issue, I upgraded my Flask-JWT-Extended
package to Flask-JWT-Extended==4.1.0
For Reference:
Please Visit this page: https://flask-jwt-extended.readthedocs.io/en/stable/
In Python 3, this mental model is pretty straight-forward:
- Encoding is the process of converting a
str
to abytes
object - Decoding is the process of converting a
bytes
object to astr
┏━━━━━━━┓ ┏━━━━━━━┓
┃ ┃ -> encoding -> ┃ ┃
┃ str ┃ ┃ bytes ┃
┃ ┃ <- decoding <- ┃ ┃
┗━━━━━━━┛ ┗━━━━━━━┛
In your case, you are calling data.decode("UTF-8")
, but the variable is already a str
object and is already decoded. So just refer to data
directly if a string is what you need.
If anyone getting the same error while participating in Kaggle for a Logistic REgre, here is the solution :
logmodel = LogisticRegression(solver='liblinear')
If you are working with Django and simple-jwt:
Here is your 100% solution
pip install PyJWT==1.7.1
my case may have been a bit rare but I was working with django and my project was running locally but not when I deployed it, it seemed as though I was getting multiple dependency errors because I was doing: pip freeze > requirements.txt
doing this fixed the issue:
pip3 freeze > requirements.txt
First install suitable JWT
pip3 install PyJWT
then in your code
token.encode().decode('UTF-8')
this worked me, I think this will help you