def better_exchook(etype, value, tb, debugshell=False, autodebugshell=True, file=None, with_color=None):
    """
    Replacement for sys.excepthook.

    :param etype: exception type
    :param value: exception value
    :param tb: traceback
    :param bool debugshell: spawn a debug shell at the context of the exception
    :param bool autodebugshell: if env DEBUG is an integer != 0, it will spawn a debug shell
    :param io.TextIOBase|io.StringIO file: output stream where we will print the traceback and exception information.
        stderr by default.
    :param bool|None with_color: whether to use ANSI escape codes for colored output
    """
    if file is None:
        file = sys.stderr

    def output(ln):
        """
        :param str ln:
        :return: nothing, prints to ``file``
        """
        file.write(ln + "\n")

    color = Color(enable=with_color)
    output(color("EXCEPTION", color.fg_colors[1], bold=True))
    all_locals, all_globals = {}, {}
    if tb is not None:
        print_tb(tb, allLocals=all_locals, allGlobals=all_globals, file=file, withTitle=True, with_color=color.enable)
    else:
        output(color("better_exchook: traceback unknown", color.fg_colors[1]))

    import types

    # noinspection PyShadowingNames
    def _some_str(value):
        """
        :param object value:
        :rtype: str
        """
        # noinspection PyBroadException
        try:
            return str(value)
        except Exception:
            return '<unprintable %s object>' % type(value).__name__

    # noinspection PyShadowingNames
    def _format_final_exc_line(etype, value):
        value_str = _some_str(value)
        if value is None or not value_str:
            line = color("%s" % etype, color.fg_colors[1])
        else:
            line = color("%s" % etype, color.fg_colors[1]) + ": %s" % (value_str,)
        return line

    # noinspection PyUnresolvedReferences
    if (isinstance(etype, BaseException) or
            (hasattr(types, "InstanceType") and isinstance(etype, types.InstanceType)) or
            etype is None or type(etype) is str):
        output(_format_final_exc_line(etype, value))
    else:
        output(_format_final_exc_line(etype.__name__, value))

    if autodebugshell:
        # noinspection PyBroadException
        try:
            debugshell = int(os.environ["DEBUG"]) != 0
        except Exception:
            pass
    if debugshell:
        output("---------- DEBUG SHELL -----------")
        debug_shell(user_ns=all_locals, user_global_ns=all_globals, traceback=tb)
    file.flush()
Replacement for sys.excepthook.

    :param etype: exception type
    :param value: exception value
    :param tb: traceback
    :param bool debugshell: spawn a debug shell at the context of the exception
    :param bool autodebugshell: if env DEBUG is an integer != 0, it will spawn a debug shell
    :param io.TextIOBase|io.StringIO file: output stream where we will print the traceback and exception information.
        stderr by default.
    :param bool|None with_color: whether to use ANSI escape codes for colored output