| 911 | return traceback, extraline |
| 912 | |
| 913 | def repr_excinfo( |
| 914 | self, excinfo: ExceptionInfo[BaseException] |
| 915 | ) -> "ExceptionChainRepr": |
| 916 | repr_chain: List[ |
| 917 | Tuple[ReprTraceback, Optional[ReprFileLocation], Optional[str]] |
| 918 | ] = [] |
| 919 | e: Optional[BaseException] = excinfo.value |
| 920 | excinfo_: Optional[ExceptionInfo[BaseException]] = excinfo |
| 921 | descr = None |
| 922 | seen: Set[int] = set() |
| 923 | while e is not None and id(e) not in seen: |
| 924 | seen.add(id(e)) |
| 925 | if excinfo_: |
| 926 | reprtraceback = self.repr_traceback(excinfo_) |
| 927 | reprcrash: Optional[ReprFileLocation] = ( |
| 928 | excinfo_._getreprcrash() if self.style != "value" else None |
| 929 | ) |
| 930 | else: |
| 931 | # Fallback to native repr if the exception doesn't have a traceback: |
| 932 | # ExceptionInfo objects require a full traceback to work. |
| 933 | reprtraceback = ReprTracebackNative( |
| 934 | traceback.format_exception(type(e), e, None) |
| 935 | ) |
| 936 | reprcrash = None |
| 937 | |
| 938 | repr_chain += [(reprtraceback, reprcrash, descr)] |
| 939 | if e.__cause__ is not None and self.chain: |
| 940 | e = e.__cause__ |
| 941 | excinfo_ = ( |
| 942 | ExceptionInfo.from_exc_info((type(e), e, e.__traceback__)) |
| 943 | if e.__traceback__ |
| 944 | else None |
| 945 | ) |
| 946 | descr = "The above exception was the direct cause of the following exception:" |
| 947 | elif ( |
| 948 | e.__context__ is not None and not e.__suppress_context__ and self.chain |
| 949 | ): |
| 950 | e = e.__context__ |
| 951 | excinfo_ = ( |
| 952 | ExceptionInfo.from_exc_info((type(e), e, e.__traceback__)) |
| 953 | if e.__traceback__ |
| 954 | else None |
| 955 | ) |
| 956 | descr = "During handling of the above exception, another exception occurred:" |
| 957 | else: |
| 958 | e = None |
| 959 | repr_chain.reverse() |
| 960 | return ExceptionChainRepr(repr_chain) |
| 961 | |
| 962 | |
| 963 | @attr.s(eq=False, auto_attribs=True) |