I'm trying to have a python2.7/3+ compatible code. And I'm struggling to handle raising a ValueError with a message in unicode correctly. I found very little results for "exception str() failed".
Here's the code:
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import logging
from builtins import str
from future import standard_library
standard_library.install_aliases()
conf = {}
try:
conf["key"]
except KeyError:
msg = "Message"
msg += " + ünicode"
logging.warn(msg)
raise ValueError(msg)
In python3 this is working as expected, but in python 2.7 as soon as msg
contain unicode it gives:
WARNING:root:Message + ünicode
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
ValueError: <exception str() failed>
Notice how the logging can handle the unicode string but not ValueError
. What am I doing wrong ? How can I have a unicode error message in both python 2.7 and 3+ ?
You can try to encode the msg convert it to string for Python 2, e.g.
from sys import version_info
if version_info.major == 2:
raise ValueError(msg.encode('utf-8'))
elif version_info.major == 3:
raise ValueError(msg)
else:
raise YourException("not supported Python version")
Upate: Below is the workaround without importing any package if you only use from __future__ import unicode_literals
without python-future package:
if isinstance(msg, str):
raise ValueError(msg)
else:
raise ValueError(msg.encode('utf-8'))
Wait for patch from Python code level(e.g. six, future package) is nearly impossible as the problematic code is in C code level in pythonrun.c, it seems like PyObject_Str(value)
execution for unicode string returned null