Given a traceback or an exception, return a tuple of chained exceptions and current traceback to inspect. This will deal with selecting the right ``__cause__`` or ``__context__`` as well as handling cycles, and return a flattened list of exceptions we can ju
(self, tb_or_exc)
| 680 | self._safe_repr(oldvalue, expr))) |
| 681 | |
| 682 | def _get_tb_and_exceptions(self, tb_or_exc): |
| 683 | """ |
| 684 | Given a traceback or an exception, return a tuple of chained exceptions |
| 685 | and current traceback to inspect. |
| 686 | |
| 687 | This will deal with selecting the right ``__cause__`` or ``__context__`` |
| 688 | as well as handling cycles, and return a flattened list of exceptions we |
| 689 | can jump to with do_exceptions. |
| 690 | |
| 691 | """ |
| 692 | _exceptions = [] |
| 693 | if isinstance(tb_or_exc, BaseException): |
| 694 | traceback, current = tb_or_exc.__traceback__, tb_or_exc |
| 695 | |
| 696 | while current is not None: |
| 697 | if current in _exceptions: |
| 698 | break |
| 699 | _exceptions.append(current) |
| 700 | if current.__cause__ is not None: |
| 701 | current = current.__cause__ |
| 702 | elif ( |
| 703 | current.__context__ is not None and not current.__suppress_context__ |
| 704 | ): |
| 705 | current = current.__context__ |
| 706 | |
| 707 | if len(_exceptions) >= self.MAX_CHAINED_EXCEPTION_DEPTH: |
| 708 | self.message( |
| 709 | f"More than {self.MAX_CHAINED_EXCEPTION_DEPTH}" |
| 710 | " chained exceptions found, not all exceptions" |
| 711 | "will be browsable with `exceptions`." |
| 712 | ) |
| 713 | break |
| 714 | else: |
| 715 | traceback = tb_or_exc |
| 716 | return tuple(reversed(_exceptions)), traceback |
| 717 | |
| 718 | @contextmanager |
| 719 | def _hold_exceptions(self, exceptions): |
no test coverage detected