Truncate the given recursive traceback trying to find the starting point of the recursion. The detection is done by going through each traceback entry and finding the point in which the locals of the frame are equal to the locals of a previous frame (see ``recursioni
(
self, traceback: Traceback
)
| 869 | return ReprTraceback(entries, extraline, style=self.style) |
| 870 | |
| 871 | def _truncate_recursive_traceback( |
| 872 | self, traceback: Traceback |
| 873 | ) -> Tuple[Traceback, Optional[str]]: |
| 874 | """Truncate the given recursive traceback trying to find the starting |
| 875 | point of the recursion. |
| 876 | |
| 877 | The detection is done by going through each traceback entry and |
| 878 | finding the point in which the locals of the frame are equal to the |
| 879 | locals of a previous frame (see ``recursionindex()``). |
| 880 | |
| 881 | Handle the situation where the recursion process might raise an |
| 882 | exception (for example comparing numpy arrays using equality raises a |
| 883 | TypeError), in which case we do our best to warn the user of the |
| 884 | error and show a limited traceback. |
| 885 | """ |
| 886 | try: |
| 887 | recursionindex = traceback.recursionindex() |
| 888 | except Exception as e: |
| 889 | max_frames = 10 |
| 890 | extraline: Optional[str] = ( |
| 891 | "!!! Recursion error detected, but an error occurred locating the origin of recursion.\n" |
| 892 | " The following exception happened when comparing locals in the stack frame:\n" |
| 893 | " {exc_type}: {exc_msg}\n" |
| 894 | " Displaying first and last {max_frames} stack frames out of {total}." |
| 895 | ).format( |
| 896 | exc_type=type(e).__name__, |
| 897 | exc_msg=str(e), |
| 898 | max_frames=max_frames, |
| 899 | total=len(traceback), |
| 900 | ) |
| 901 | # Type ignored because adding two instances of a List subtype |
| 902 | # currently incorrectly has type List instead of the subtype. |
| 903 | traceback = traceback[:max_frames] + traceback[-max_frames:] # type: ignore |
| 904 | else: |
| 905 | if recursionindex is not None: |
| 906 | extraline = "!!! Recursion detected (same locals & position)" |
| 907 | traceback = traceback[: recursionindex + 1] |
| 908 | else: |
| 909 | extraline = None |
| 910 | |
| 911 | return traceback, extraline |
| 912 | |
| 913 | def repr_excinfo( |
| 914 | self, excinfo: ExceptionInfo[BaseException] |
no test coverage detected