The only difference between your two approaches is that print_exc() prints a formatted exception. For SyntaxError , which includes formatting the information in this exception, which includes the actual string that caused the problem.
For the trace itself, print_exc() uses sys.exc_info()[2] , the same information that you already use to create the trace. In other words, it does not receive more information than you already do, but you ignore the exception information itself:
>>> import traceback >>> try: ... compile('Hmmm, nope!', '<stdin>', 'exec') ... except SyntaxError as e: ... print ''.join(traceback.format_exception_only(type(e), e)) ... File "<stdin>", line 1 Hmmm, nope! ^ SyntaxError: invalid syntax
Here traceback.format_exception_only() is the undocumented function used by traceback.print_exc() to format the exception value. All information is available to you for the exception:
>>> dir(e) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', 'args', 'filename', 'lineno', 'message', 'msg', 'offset', 'print_file_and_line', 'text'] >>> e.args ('invalid syntax', ('<stdin>', 1, 11, 'Hmmm, nope!\n')) >>> e.filename, e.lineno, e.offset, e.text ('<stdin>', 1, 11, 'Hmmm, nope!\n')
Also see the documentation for traceback.print_exception() :
(3) if the type is SyntaxError , and the value is in the appropriate format, it prints the line where the syntax error occurred, using a caret indicating the approximate position of the error.
and SyntaxError documentation :
Instances of this class have filename , lineno , offset and text attributes for easier access to details. str() exception instance returns only the message.
The fact that the syntax error line is not included in the trace is logical; code with a syntax error could not be executed, so no execution block was created for it. And the exception is thrown by the compile() function, the bottommost frame of execution.
As such, you are stuck with your ugly approach; this is the right approach for handling SyntaxError exceptions. However attributes documented.
Note that exception.message usually set to exception.args[0] , and str(exception) usually gives you the same message (if args longer you get str(exception.args) ), although some types of exceptions provide a custom __str__ which often just gives you exception.args[0] ).