You problem has nothing to do with IDLE. The behavior you see is all from Python. Running current repository CPython interactively, from a command line, we see the behavior you reported.
Python 3.7.0a2+ (heads/pr_3947:01eae2f721, Oct 22 2017, 14:06:43)
[MSC v.1900 32 bit (Intel)] on win32
>>> raise KeyError('This is a \n Line break')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'This is a \n Line break'
>>> s = 'This is a \n Line break'
>>> s
'This is a \n Line break'
>>> print(s)
This is a
Line break
>>> raise Exception('This is a \n Line break')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: This is a
Line break
>>> raise IndexError(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: This is a
Line break
>>> try:
... raise KeyError('This is a \n Line break')
... except KeyError as e:
... print(e)
'This is a \n Line break'
>>> try:
... raise KeyError('This is a \n Line break')
... except KeyError as e:
... print(e.args[0])
This is a
Line break
I don't know why KeyError acts differently from even IndexError, but printing e.args[0] should work for all exceptions.
EDIT
The reason for the difference is given in this old tracker issue, which quotes a comment in the KeyError
source code:
/* 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__().
*/
This section appears in the KeyError_str
object definition in Objects/exceptions.c
of the Python source code.
I will mention your issue as another manifestation of this difference.