Handling exceptions in Python 3 Please can you review my standard exception handler for Python 3.x. It is located under the # +=+= line. The code above the line is to create an exception and so the code is code complete and runs standalone.
The code is just a standard exception formatter, so users are presented with easier to read messages rather than stack traces. This is a common idiom in many Python projects. But many / all don't format to the extent I have.
I have searched a lot, but I can't find anything better. I expected to find something on GitHub, but was unfruitful. If you find a way to improve this, please post it here so that I and others will know.
import inspect
import os
import sys
import traceback

if __name__ == '__main__':
    try:
        x = 42/0

    # +=+=+=+=+=+=+=+=+=+=+=+=+=
    except KeyboardInterrupt as e: # Ctrl-C
        raise e
    except SystemExit as e: # sys.exit()
        raise e
    except Exception as e :
        exc_type, exc_obj, exc_tb = sys.exc_info()
        scriptName = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        functionName = inspect.currentframe().f_code.co_name
        print('=======================================================================================================')
        print('Unhandled exception: ', exc_type, scriptName, 'at line', exc_tb.tb_lineno)
        print('                      in function', functionName)
        print('                     ', str(e))

        traceback.print_exc()
        sys.exit(1)
Rather than using as e then raise e you can just omit e.

except KeyboardInterrupt as e:
    raise e


except KeyboardInterrupt:
    raise


Rather than specifying an except block for KeyboardInterrupt and SystemExit you can just specify them in the same except by passing a tuple.

except KeyboardInterrupt:
    raise
except SystemExit:
    raise


except (KeyboardInterrupt, SystemExit):
    raise


Both KeyboardInterrupt and SystemExit are not subclasses of Exception so you do not need to handle them. The exceptions will propagate like normal.
You may want to familiarize yourself with the exception hierarchy.

You can get all the information that sys.exc_info() gives from e.

exc_type, exc_obj, exc_tb = sys.exc_info()


exc_type, exc_obj, exc_tb = type(e), e, e.__traceback__


You can get the current frame from exc_tb rather than inspect.currentframe(). This makes the code more portable if you ever decide to move the code into a function to format tracebacks.

frame = inspect.currentframe()


frame = exc_tb.tb_frame


Please follow PEP 8 and name variables with snake_case. It is very easy to see the code you've taken from the Python docs and the code you've written yourself / taken from somewhere else.

If you're going to hard code the == at least use * to build it the size you want.

print('=======================================================================================================')


print('=' * 103)


Better yet just print to the size of the terminal.
print('=' * os.get_terminal_size().columns)


I would prefer to use f-strings if available.

print('Unhandled exception: ', exc_type, script_name, 'at line', exc_tb.tb_lineno)


print(f'Unhandled exception:  {exc_type} {script_name} at line {exc_tb.tb_lineno}')



if __name__ == '__main__':
    try:
        x = 42/0
    except Exception as e:
        exc_tb = e.__traceback__
        script_name = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        function_name = exc_tb.tb_frame.f_code.co_name
        print('=' * os.get_terminal_size().columns)
        print(f'Unhandled exception:  {type(e)} {script_name} at line {exc_tb.tb_lineno}')
        print(f'                      in function {function_name}')
        print(f'                      {e}')

        traceback.print_exc()
        raise SystemExit(1)