Пример #1
0
def test_collect_try_except_info(data_regression):
    method_to_info = {}
    for key, method in sorted(dict(globals()).items()):
        if key.startswith('_method'):
            info = collect_try_except_info(method.__code__,
                                           use_func_first_line=True)

            if key == "_method_try_except":
                if sys.version_info[:2] == (3, 7):
                    for try_except_info in info:
                        # On 3.7 the last bytecode actually has a different start line.
                        if try_except_info.except_end_line == 8:
                            try_except_info.except_end_line = 9

                elif sys.version_info[:2] >= (3, 8):
                    for try_except_info in info:
                        # On 3.8 the last bytecode actually has a different start line.
                        if try_except_info.except_end_line == 7:
                            try_except_info.except_end_line = 9

            method_to_info[key] = [str(x) for x in info]

            method_to_info[key] = [str(x) for x in info]

    data_regression.check(method_to_info)
    def trace_dispatch_and_unhandled_exceptions(self, frame, event, arg):
        # print('trace_dispatch_and_unhandled_exceptions', event, frame.f_code.co_name, frame.f_code.co_filename, frame.f_code.co_firstlineno)
        if self._frame_trace_dispatch is not None:
            # This deals with raised exceptions
            self._frame_trace_dispatch = self._frame_trace_dispatch(frame, event, arg)

        if event == 'exception':
            self._last_exc_arg = arg
            self._raise_lines.add(frame.f_lineno)
            self._last_raise_line = frame.f_lineno

        elif event == 'return' and self._last_exc_arg is not None:
            # For unhandled exceptions we actually track the return when at the topmost level.
            try:
                py_db, t, additional_info = self._args[0:3]
                if not additional_info.suspended_at_unhandled:  # Note: only check it here, don't set.
                    if frame.f_lineno in self._raise_lines:
                        stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)

                    else:
                        if self._try_except_info is None:
                            self._try_except_info = collect_try_except_info(frame.f_code)
                        if not self._try_except_info:
                            # Consider the last exception as unhandled because there's no try..except in it.
                            stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)
                        else:
                            # Now, consider only the try..except for the raise
                            valid_try_except_infos = []
                            for try_except_info in self._try_except_info:
                                if try_except_info.is_line_in_try_block(self._last_raise_line):
                                    valid_try_except_infos.append(try_except_info)

                            if not valid_try_except_infos:
                                stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)

                            else:
                                # Note: check all, not only the "valid" ones to cover the case
                                # in "tests_python.test_tracing_on_top_level.raise_unhandled10"
                                # where one try..except is inside the other with only a raise
                                # and it's gotten in the except line.
                                for try_except_info in self._try_except_info:
                                    if try_except_info.is_line_in_except_block(frame.f_lineno):
                                        if (
                                                frame.f_lineno == try_except_info.except_line or
                                                frame.f_lineno in try_except_info.raise_lines_in_except
                                            ):
                                            # In a raise inside a try..except block or some except which doesn't
                                            # match the raised exception.
                                            stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)
                                            break
                                        else:
                                            break  # exited during the except block (no exception raised)
            finally:
                # Remove reference to exception after handling it.
                self._last_exc_arg = None

        # IFDEF CYTHON
        # return SafeCallWrapper(self.trace_dispatch_and_unhandled_exceptions)
        # ELSE
        return self.trace_dispatch_and_unhandled_exceptions
def test_collect_try_except_info(data_regression):
    method_to_info = {}
    for key, method in sorted(dict(globals()).items()):
        if key.startswith('_method'):
            info = collect_try_except_info(method.__code__, use_func_first_line=True)

            if sys.version_info[:2] >= (3, 7):
                for try_except_info in info:
                    # On 3.7 the last bytecode actually has a different start line.
                    if try_except_info.except_end_line == 8:
                        try_except_info.except_end_line = 9

            method_to_info[key] = [str(x) for x in info]

    data_regression.check(method_to_info)
Пример #4
0
def test_collect_try_except_info2():
    def method():
        try:
            raise AssertionError
        except:
            _a = 10
            raise
        finally:
            _b = 20
        _c = 20

    code = method.__code__
    lst = collect_try_except_info(code, use_func_first_line=True)
    if IS_CPYTHON:
        assert str(lst) == '[{try:1 except 3 end block 5 raises: 5}]'
    else:
        assert lst == []
def test_collect_try_except_info2():

    def method():
        try:
            raise AssertionError
        except:
            _a = 10
            raise
        finally:
            _b = 20
        _c = 20

    code = method.__code__
    lst = collect_try_except_info(code, use_func_first_line=True)
    if IS_CPYTHON:
        assert str(lst) == '[{try:1 except 3 end block 5 raises: 5}]'
    else:
        assert lst == []
    def trace_dispatch_and_unhandled_exceptions(self, frame, event, arg):
        # print('trace_dispatch_and_unhandled_exceptions', event, frame.f_code.co_name, frame.f_code.co_filename, frame.f_code.co_firstlineno)
        if self._frame_trace_dispatch is not None:
            self._frame_trace_dispatch = self._frame_trace_dispatch(frame, event, arg)

        if event == 'exception':
            self._last_exc_arg = arg
            self._raise_lines.add(frame.f_lineno)
            self._last_raise_line = frame.f_lineno

        elif event == 'return' and self._last_exc_arg is not None:
            # For unhandled exceptions we actually track the return when at the topmost level.
            try:
                py_db, t, additional_info = self._args[0:3]
                if not additional_info.suspended_at_unhandled:  # Note: only check it here, don't set.
                    if frame.f_lineno in self._raise_lines:
                        stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)

                    else:
                        if self._try_except_info is None:
                            self._try_except_info = collect_try_except_info(frame.f_code)
                        if not self._try_except_info:
                            # Consider the last exception as unhandled because there's no try..except in it.
                            stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)
                        else:
                            # Now, consider only the try..except for the raise
                            valid_try_except_infos = []
                            for try_except_info in self._try_except_info:
                                if try_except_info.is_line_in_try_block(self._last_raise_line):
                                    valid_try_except_infos.append(try_except_info)

                            if not valid_try_except_infos:
                                stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)

                            else:
                                # Note: check all, not only the "valid" ones to cover the case
                                # in "tests_python.test_tracing_on_top_level.raise_unhandled10"
                                # where one try..except is inside the other with only a raise
                                # and it's gotten in the except line.
                                for try_except_info in self._try_except_info:
                                    if try_except_info.is_line_in_except_block(frame.f_lineno):
                                        if (
                                                frame.f_lineno == try_except_info.except_line or
                                                frame.f_lineno in try_except_info.raise_lines_in_except
                                            ):
                                            # In a raise inside a try..except block or some except which doesn't
                                            # match the raised exception.
                                            stop_on_unhandled_exception(py_db, t, additional_info, self._last_exc_arg)
                                            break
                                        else:
                                            break  # exited during the except block (no exception raised)
            finally:
                # Remove reference to exception after handling it.
                self._last_exc_arg = None

        # IFDEF CYTHON
        # ret = SafeCallWrapper(self.trace_dispatch_and_unhandled_exceptions)
        # ELSE
        ret = self.trace_dispatch_and_unhandled_exceptions
        # ENDIF
        
        # Need to reset (the call to _frame_trace_dispatch may have changed it).
        frame.f_trace = ret
        return ret