Beispiel #1
0
def _remove_frame_from_stack(tbss: StackSummary,
                             framename: str) -> StackSummary:
    filtered_stack_list: List[traceback.FrameSummary] = \
        list(filter(lambda frame: getattr(frame,
                                          'filename') != framename, tbss))
    filtered_stack: StackSummary = StackSummary.from_list(filtered_stack_list)
    return filtered_stack
Beispiel #2
0
def iter_traceback(tb=None, enforce_most_recent_call_first=False):
    """
    Iterates a traceback of various formats:
      - traceback (types.TracebackType)
      - frame object (types.FrameType)
      - stack summary (traceback.StackSummary)

    :param types.TracebackType|types.FrameType|StackSummary|None tb: traceback. if None, will use sys._getframe
    :param bool enforce_most_recent_call_first:
        Frame or stack summery: most recent call first (top of the stack is the first entry in the result)
        Traceback: most recent call last
        If True, and we get traceback, will unroll and reverse, such that we have always the most recent call first.
    :return: yields the frames (types.FrameType)
    :rtype: list[types.FrameType|DummyFrame]
    """
    if tb is None:
        tb = get_current_frame()

    def is_stack_summary(_tb):
        return isinstance(_tb, StackSummary)

    is_frame = inspect.isframe
    is_traceback = inspect.istraceback
    assert is_traceback(tb) or is_frame(tb) or is_stack_summary(tb)
    # Frame or stack summery: most recent call first
    # Traceback: most recent call last
    if is_traceback(tb) and enforce_most_recent_call_first:
        frames = list(iter_traceback(tb))
        for frame in frames[::-1]:
            yield frame
        return

    _tb = tb
    while _tb is not None:
        if is_frame(_tb):
            frame = _tb
        elif is_stack_summary(_tb):
            if isinstance(_tb[0], ExtendedFrameSummary):
                frame = _tb[0].tb_frame
            else:
                frame = DummyFrame.from_frame_summary(_tb[0])
        else:
            frame = _tb.tb_frame
        yield frame
        if is_frame(_tb):
            _tb = _tb.f_back
        elif is_stack_summary(_tb):
            _tb = StackSummary.from_list(_tb[1:])
            if not _tb:
                _tb = None
        else:
            _tb = _tb.tb_next
Beispiel #3
0
def except_hook(
    exc_type: Type[BaseException], exc_value: BaseException, tb: TracebackType
) -> None:
    exception_config: Union[DeveloperExceptionConfig, None] = getattr(
        exc_value, _typer_developer_exception_attr_name, None
    )
    standard_traceback = os.getenv("_TYPER_STANDARD_TRACEBACK")
    if (
        standard_traceback
        or not exception_config
        or not exception_config.pretty_exceptions_enable
    ):
        _original_except_hook(exc_type, exc_value, tb)
        return
    typer_path = os.path.dirname(__file__)
    click_path = os.path.dirname(click.__file__)
    supress_internal_dir_names = [typer_path, click_path]
    exc = exc_value
    if rich:
        rich_tb = Traceback.from_exception(
            type(exc),
            exc,
            exc.__traceback__,
            show_locals=exception_config.pretty_exceptions_show_locals,
            suppress=supress_internal_dir_names,
        )
        console_stderr.print(rich_tb)
        return
    tb_exc = traceback.TracebackException.from_exception(exc)
    stack: List[FrameSummary] = []
    for frame in tb_exc.stack:
        if any(
            [frame.filename.startswith(path) for path in supress_internal_dir_names]
        ):
            if not exception_config.pretty_exceptions_short:
                # Hide the line for internal libraries, Typer and Click
                stack.append(
                    traceback.FrameSummary(
                        filename=frame.filename,
                        lineno=frame.lineno,
                        name=frame.name,
                        line="",
                    )
                )
        else:
            stack.append(frame)
    # Type ignore ref: https://github.com/python/typeshed/pull/8244
    final_stack_summary = StackSummary.from_list(stack)  # type: ignore
    tb_exc.stack = final_stack_summary
    for line in tb_exc.format():
        print(line, file=sys.stderr)
    return
Beispiel #4
0
 def __post_init__(self, function, test_id):
     file_frame = FrameSummary(
         inspect.getfile(function),
         docs_start_lineno(function) + self.path.line,
         function.__name__,
         lookup_line=False,
     )
     dynamic_frame = FrameSummary(test_id,
                                  1,
                                  function.__name__,
                                  lookup_line=False,
                                  line=self.path)
     self.stack = StackSummary.from_list([file_frame, dynamic_frame])
Beispiel #5
0
def _exception_handler(loop, context):
    ''' Last resort exception handler

    This will only catch exceptions that happen in the main thread. Others very
    well may go entirely unnoticed and unlogged.

    Some exceptions are unexpected, so we end up here. For these we kill
    ourselves after logging about the exception.

    Other exceptions are impossible to catch before we get here. For example, a
    client failing the TLS handshake with us. (ugh what the f**k). For these we
    notify the state machine so it can react.
    '''
    # Check for exceptions that should not be fatal and we should tell other
    # parts of the code about so they can react intelligently
    if 'exception' in context:
        exception_type = type(context['exception'])
        # Check for recoverable TLS errors
        if exception_type == ssl.SSLError:
            if 'transport' in context:
                machine.notif_sslerror(context['exception'],
                                       context['transport'])
                return
            else:
                log.warn(
                    'SSLError caught without a transport too. Cannot pass ' +
                    'to state machine to handle gracefully.')
        # Additional recoverable errors would continue here
    # All other exceptions. These are fatal
    log.error('%s', context['message'])
    if 'exception' in context:
        log.error('%s %s', type(context['exception']), context['exception'])
    if 'handle' in context:
        log.error(context['handle'])
    if 'source_traceback' in context:
        log.error('Traceback:')
        summary = StackSummary.from_list(context['source_traceback'])
        for line_super in summary.format():
            # The above line has multiple lines in it
            for line in line_super.split('\n'):
                if len(line):
                    log.error('  %s', line)
    else:
        log.error(
            'Traceback not available. Maybe run with PYTHONASYNCIODEBUG=1')
    machine.change_state_fatal_error()
Beispiel #6
0
def generate_move_process(generate_move: cu.GenMove, moves_q: mp.Queue):
    from traceback import StackSummary
    from random import seed as random_seed
    import io
    from time import time
    import pickle
    from contextlib import redirect_stderr, redirect_stdout

    logger = logging.getLogger(__name__)
    f_stderr, f_stdout = io.StringIO(), io.StringIO()

    gma: GenMoveArgs = moves_q.get()
    np.random.seed(gma.seed)
    random_seed(gma.seed)

    try:
        with redirect_stdout(f_stdout), redirect_stderr(f_stderr):
            t0 = time()
            returned = generate_move(gma.board, gma.player, gma.state)
            saved_state = None
            if isinstance(returned, tuple):
                action = returned[0]
                if len(returned) > 1:
                    saved_state = returned[1]
            else:
                action = returned

            move_time = time() - t0
        stdout, stderr = f_stdout.getvalue(), f_stderr.getvalue()
        result = GenMoveSuccess(stdout, stderr, move_time, action, saved_state)
    except Exception as e:
        logger.exception("An exception was thrown by the agent.")
        error_msg = repr(e) + "\n"
        extracted_list = traceback.extract_tb(e.__traceback__)
        for item in StackSummary.from_list(extracted_list).format():
            error_msg += str(item)
        stdout, stderr = f_stdout.getvalue(), f_stderr.getvalue()
        result = GenMoveFailure(stdout, stderr, error_msg)

    try:
        moves_q.put(result)
    except pickle.PickleError:
        logger.exception(
            "Internal error in trying to send the result, probably caused by saved_state"
        )
        moves_q.put(GenMoveSuccess(stdout, stderr, move_time, action, None))
Beispiel #7
0
def _exception_handler(loop, context):
    log.error('%s', context['message'])
    if 'exception' in context:
        log.error(context['exception'])
    if 'handle' in context:
        log.error(context['handle'])
    if 'source_traceback' in context:
        log.error('Traceback:')
        summary = StackSummary.from_list(context['source_traceback'])
        for line_super in summary.format():
            # The above line has multiple lines in it
            for line in line_super.split('\n'):
                if len(line):
                    log.error('  %s', line)
    else:
        log.error('Traceback not available. Run with PYTHONASYNCIODEBUG=1')
    machine.change_state_fatal_error()
Beispiel #8
0
    def format(self, record) -> str:

        # set for different levels
        format_orig = self._style._fmt
        self._style._fmt = self.msg_fmt[record.levelname]

        # preprocess \n
        line_count = 0
        for s in record.msg:
            if s == '\n':
                line_count += 1
                record.msg = record.msg[1:]
            else:
                break
        if record.msg:
            self._style._fmt = line_count * '\n' + self._style._fmt
        else:
            self._style._fmt = line_count * '\n'

        if record.levelno >= self.stack_level and record.levelno != logging.MAIL and record.msg[:
                                                                                                9] != 'Traceback':
            record.stack_info = ''.join(
                StackSummary.from_list(
                    extract_stack()
                    [:self._stack_prune]).format())  # self._stack_prune

        # make it colorful
        levelname = record.levelname
        if self.use_color and levelname in COLORS:
            levelname_color = COLOR_SEQ % (
                30 + COLORS[levelname]) + record.levelname + RESET_SEQ
            record.levelname = levelname_color

        self.datefmt = '%m/%d/%Y %I:%M:%S %p'
        result = logging.Formatter.format(self, record)

        self._style._fmt = format_orig
        record.levelname = levelname

        return result
Beispiel #9
0
def format_exc(name='mlchain', tb=None, exception=None):
    if exception is None:
        formatted_lines = traceback.format_exc().splitlines()
    else:
        formatted_lines = []
        if tb is not None:
            for item in StackSummary.from_list(extract_tb(tb)).format():
                str_item = str(item)
                if str_item.endswith("\n"):
                    formatted_lines.append(str_item[:-1])
                else:
                    formatted_lines.append(str_item)
        formatted_lines += [
            x for x in re.split('(\\\\n)|(\\n)', str(exception))
            if x not in ["\\n", "\n", "", None]
        ]

    output = []
    kt = True
    last_mlchain_append = -1
    for x in formatted_lines:
        output.append(x)
        # if x.strip().startswith("File"):
        #     if ('site-packages/mlchain' in x or 'site-packages/trio' in x) and not ("mlchain.base.exceptions" in x or "AssertionError" in x):
        #         kt = False
        #     else:
        #         kt = True

        # if kt or 'AssertionError' in x or 'mlchain.base.exceptions' in x:
        #     if x.startswith("'), AssertionError"):
        #         output.append("\n" + x[4:])
        #     else:
        #         output.append(x)
        # elif last_mlchain_append != len(output):
        #     output.append('  File "{}" collapsed errors'.format(name))
        #     last_mlchain_append = len(output)

    return "\n".join(output) + "\n"
Beispiel #10
0
def format_exc(name='mlchain', tb=None, exception=None, return_str=True):
    if exception is None:
        formatted_lines = traceback.format_exc().splitlines()
    else:
        formatted_lines = []
        if tb is not None:
            for item in StackSummary.from_list(extract_tb(tb)).format():
                str_item = str(item)
                if str_item.endswith("\n"):
                    formatted_lines.append(str_item[:-1])
                else:
                    formatted_lines.append(str_item)
        formatted_lines += [
            x for x in re.split('(\\\\n)|(\\n)', str(exception))
            if x not in ["\\n", "\n", "", None]
        ]

    output = []
    for x in formatted_lines:
        output.append(x)

    if return_str:
        return "\n".join(output)
    return output
Beispiel #11
0
from contextlib import suppress

# External
from async_tools import Loopable
from async_tools.abstract import Loopable as AbstractLoopable

# Project
from ._helper import reject, fulfill, resolve

# Generic types
K = T.TypeVar("K")
L = T.TypeVar("L")

# Fake stacktrace information for use when no stack can be recovered from promise
_FAKE_STACK = list(
    StackSummary.from_list([("unknown", 0, "unknown", "invalid")]))


class ChainLink(T.Awaitable[K], Loopable):
    @staticmethod
    def log_unhandled_exception(promise: "ChainLink[T.Any]",
                                fut: "Future[T.Any]") -> None:
        assert fut.done()

        get_loop: T.Callable[[], AbstractEventLoop] = getattr(
            fut, "get_loop", None)
        loop: AbstractEventLoop = get_loop() if callable(
            get_loop) else getattr(fut, "_loop", None)

        assert loop is not None
Beispiel #12
0
def handle_exceptions(err: Exception):
    msg = '\n'.join(['', ''.join(StackSummary.from_list(extract_tb(err.__traceback__)).format()), repr(err)])
    current_app.logger.error(msg)
    return jsonify(code=500, error=repr(err), data=None), 200
Beispiel #13
0
def format_tb(tb=None, limit=None, allLocals=None, allGlobals=None, withTitle=False, with_color=None, with_vars=None):
    """
    :param types.TracebackType|types.FrameType|StackSummary tb: traceback. if None, will use sys._getframe
    :param int|None limit: limit the traceback to this number of frames. by default, will look at sys.tracebacklimit
    :param dict[str]|None allLocals: if set, will update it with all locals from all frames
    :param dict[str]|None allGlobals: if set, will update it with all globals from all frames
    :param bool withTitle:
    :param bool|None with_color: output with ANSI escape codes for color
    :param bool with_vars: will print var content which are referenced in the source code line. by default enabled.
    :return: list of strings (line-based)
    :rtype: list[str]
    """
    if with_vars is None and is_at_exit():
        # Better to not show __repr__ of some vars, as this might lead to crashes
        # when native extensions are involved.
        with_vars = False
    if with_vars is None:
        if any([f.f_code.co_name == "__del__" for f in iter_traceback()]):
            # __del__ is usually called via the Python garbage collector (GC).
            # This can happen and very random / non-deterministic places.
            # There are cases where it is not safe to access some of the vars on the stack
            # because they might be in a non-well-defined state, thus calling their __repr__ is not safe.
            # See e.g. this bug:
            # https://github.com/tensorflow/tensorflow/issues/22770
            with_vars = False
    if with_vars is None:
        with_vars = True
    color = Color(enable=with_color)
    out = []
    def output(s1, s2=None, **kwargs):
        if kwargs:
            s1 = color(s1, **kwargs)
        if s2 is not None:
            s1 = add_indent_lines(s1, s2)
        out.append(s1 + "\n")
    def format_filename(s):
        base = os.path.basename(s)
        return (
            color('"' + s[:-len(base)], "cyan") +
            color(base, "cyan", bold=True) +
            color('"', "cyan"))
    def format_py_obj(obj):
        return color.py_syntax_highlight(pretty_print(obj))
    if tb is None:
        try:
            tb = get_current_frame()
            assert tb
        except Exception:
            output(color("format_tb: tb is None and sys._getframe() failed", "red", bold=True))
            return out
    def isstacksummary(_tb):
        return isinstance(_tb, StackSummary)
    isframe = inspect.isframe
    if withTitle:
        if isframe(tb) or isstacksummary(tb):
            output(color('Traceback (most recent call first):', "blue"))
        else:  # expect traceback-object (or compatible)
            output(color('Traceback (most recent call last):', "blue"))
    try:
        if limit is None:
            if hasattr(sys, 'tracebacklimit'):
                limit = sys.tracebacklimit
        n = 0
        _tb = tb
        class NotFound(Exception):
            pass
        def _resolve_identifier(namespace, id):
            if id[0] not in namespace:
                raise NotFound()
            obj = namespace[id[0]]
            for part in id[1:]:
                obj = getattr(obj, part)
            return obj
        def _try_set(old, prefix, func):
            if old is not None: return old
            try: return add_indent_lines(prefix, func())
            except NotFound: return old
            except Exception as e:
                return prefix + "!" + e.__class__.__name__ + ": " + str(e)
        while _tb is not None and (limit is None or n < limit):
            if isframe(_tb):
                f = _tb
            elif isstacksummary(_tb):
                if isinstance(_tb[0], ExtendedFrameSummary):
                    f = _tb[0].tb_frame
                else:
                    f = DummyFrame.from_frame_summary(_tb[0])
            else:
                f = _tb.tb_frame
            if allLocals is not None: allLocals.update(f.f_locals)
            if allGlobals is not None: allGlobals.update(f.f_globals)
            if hasattr(_tb, "tb_lineno"): lineno = _tb.tb_lineno
            elif isstacksummary(_tb): lineno = _tb[0].lineno
            else: lineno = f.f_lineno
            co = f.f_code
            filename = co.co_filename
            name = co.co_name
            output("".join([
                '  ',
                color("File ", "blue", bold=True), format_filename(filename), ", ",
                color("line ", "blue"), color("%d" % lineno, "magenta"), ", ",
                color("in ", "blue"), name]))
            if not os.path.isfile(filename):
                altfn = fallback_findfile(filename)
                if altfn:
                    output(color("    -- couldn't find file, trying this instead: ", "blue") +
                           format_filename(altfn))
                    filename = altfn
            source_code = get_source_code(filename, lineno, f.f_globals)
            if source_code:
                source_code = remove_indent_lines(replace_tab_indents(source_code)).rstrip()
                output("    line: ", color.py_syntax_highlight(source_code), color="blue")
                if not with_vars:
                    pass
                elif isinstance(f, DummyFrame) and not f.have_vars_available:
                    pass
                else:
                    output(color('    locals:', "blue"))
                    alreadyPrintedLocals = set()
                    for tokenstr in grep_full_py_identifiers(parse_py_statement(source_code)):
                        splittedtoken = tuple(tokenstr.split("."))
                        for token in [splittedtoken[0:i] for i in range(1, len(splittedtoken) + 1)]:
                            if token in alreadyPrintedLocals: continue
                            tokenvalue = None
                            tokenvalue = _try_set(tokenvalue, color("<local> ", "blue"), lambda: format_py_obj(_resolve_identifier(f.f_locals, token)))
                            tokenvalue = _try_set(tokenvalue, color("<global> ", "blue"), lambda: format_py_obj(_resolve_identifier(f.f_globals, token)))
                            tokenvalue = _try_set(tokenvalue, color("<builtin> ", "blue"), lambda: format_py_obj(_resolve_identifier(f.f_builtins, token)))
                            tokenvalue = tokenvalue or color("<not found>", "blue")
                            prefix = '      %s ' % color(".", "blue", bold=True).join(token) + color("= ", "blue", bold=True)
                            output(prefix, tokenvalue)
                            alreadyPrintedLocals.add(token)
                    if len(alreadyPrintedLocals) == 0:
                        output(color("       no locals", "blue"))
            else:
                output(color('    -- code not available --', "blue"))
            if isframe(_tb):
                _tb = _tb.f_back
            elif isstacksummary(_tb):
                _tb = StackSummary.from_list(_tb[1:])
                if not _tb:
                    _tb = None
            else:
                _tb = _tb.tb_next
            n += 1

    except Exception as e:
        output(color("ERROR: cannot get more detailed exception info because:", "red", bold=True))
        import traceback
        for l in traceback.format_exc().split("\n"):
            output("   " + l)

    return out
Beispiel #14
0
 def dump_stack(frames):
     stack = StackSummary.from_list(extract_stack(frames))
     return [{"filename": f.filename, "lineno": f.lineno, "name": f.name, "line": f.line,
              "locals": {name: repr(value) for name, value in sorted(f.locals.items())} if f.locals else None}
             for f in stack]