Catching KeyError message in Python 3
Question:
I’m having trouble catching the message in a KeyError
in Python 3 (More specifically 3.5.3).
Input:
try:
raise KeyError('some error message')
except KeyError as e:
if str(e) == 'some error message':
print('Caught error message')
else:
print("Didn't catch error message")
Output:
Didn't catch error message
Oddly, the same thing works with something like an IndexError
Input:
try:
raise IndexError('some index error message')
except IndexError as e:
if str(e) == 'some index error message':
print('Caught IndexError message')
else:
print("Didn't catch IndexError message")
Output:
Caught IndexError message
Also, this problem seems to be specific to Python 3 because you could just grab the message
attribute in Python 2.
Input:
try:
raise KeyError('some error message')
except KeyError as e:
if e.message == 'some error message':
print 'Caught error message'
else:
print "Didn't catch error message"
Output:
Caught error message
Answers:
I solved my problem by checking if my error message was in the error string:
Input:
try:
raise KeyError('some error message')
except KeyError as e:
if 'some error message' in str(e):
print('Caught error message')
else:
print("Didn't catch error message")
Output:
Caught error message
Can someone shine some light on why this works but checking for equality doesn’t?
Edit:
As KGSH pointed out, str(e)
is really 'some error message'
WITH the single quotation marks.
@Arda:
(Since I cannot comment)
After testing with this mini code:
try:
raise KeyError('some error message')
except KeyError as e:
print (str(e))
print ('some error message')
print (str(e) == 'some error message')
Here is the output:
Caught error message
‘some error message’
some error message
False
So the difference is the quotation marks.
EDIT: I would like to have someone to help me format this better.
This behavior is perfectly explained in the source code:
static PyObject *
KeyError_str(PyBaseExceptionObject *self)
{
/* If args is a tuple of exactly one item, apply repr to args[0].
This is done so that e.g. the exception raised by {}[''] prints
KeyError: ''
rather than the confusing
KeyError
alone. The downside is that if KeyError is raised with an explanatory
string, that string will be displayed in quotes. Too bad.
If args is anything else, use the default BaseException__str__().
*/
I’m having trouble catching the message in a KeyError
in Python 3 (More specifically 3.5.3).
Input:
try:
raise KeyError('some error message')
except KeyError as e:
if str(e) == 'some error message':
print('Caught error message')
else:
print("Didn't catch error message")
Output:
Didn't catch error message
Oddly, the same thing works with something like an IndexError
Input:
try:
raise IndexError('some index error message')
except IndexError as e:
if str(e) == 'some index error message':
print('Caught IndexError message')
else:
print("Didn't catch IndexError message")
Output:
Caught IndexError message
Also, this problem seems to be specific to Python 3 because you could just grab the message
attribute in Python 2.
Input:
try:
raise KeyError('some error message')
except KeyError as e:
if e.message == 'some error message':
print 'Caught error message'
else:
print "Didn't catch error message"
Output:
Caught error message
I solved my problem by checking if my error message was in the error string:
Input:
try:
raise KeyError('some error message')
except KeyError as e:
if 'some error message' in str(e):
print('Caught error message')
else:
print("Didn't catch error message")
Output:
Caught error message
Can someone shine some light on why this works but checking for equality doesn’t?
Edit:
As KGSH pointed out, str(e)
is really 'some error message'
WITH the single quotation marks.
@Arda:
(Since I cannot comment)
After testing with this mini code:
try:
raise KeyError('some error message')
except KeyError as e:
print (str(e))
print ('some error message')
print (str(e) == 'some error message')
Here is the output:
Caught error message
‘some error message’
some error message
False
So the difference is the quotation marks.
EDIT: I would like to have someone to help me format this better.
This behavior is perfectly explained in the source code:
static PyObject *
KeyError_str(PyBaseExceptionObject *self)
{
/* If args is a tuple of exactly one item, apply repr to args[0].
This is done so that e.g. the exception raised by {}[''] prints
KeyError: ''
rather than the confusing
KeyError
alone. The downside is that if KeyError is raised with an explanatory
string, that string will be displayed in quotes. Too bad.
If args is anything else, use the default BaseException__str__().
*/