Return the index of the frame/TracebackEntry where recursion originates if appropriate, None if no recursion occurred.
(self)
| 417 | return self[-1] |
| 418 | |
| 419 | def recursionindex(self) -> Optional[int]: |
| 420 | """Return the index of the frame/TracebackEntry where recursion originates if |
| 421 | appropriate, None if no recursion occurred.""" |
| 422 | cache: Dict[Tuple[Any, int, int], List[Dict[str, Any]]] = {} |
| 423 | for i, entry in enumerate(self): |
| 424 | # id for the code.raw is needed to work around |
| 425 | # the strange metaprogramming in the decorator lib from pypi |
| 426 | # which generates code objects that have hash/value equality |
| 427 | # XXX needs a test |
| 428 | key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno |
| 429 | # print "checking for recursion at", key |
| 430 | values = cache.setdefault(key, []) |
| 431 | if values: |
| 432 | f = entry.frame |
| 433 | loc = f.f_locals |
| 434 | for otherloc in values: |
| 435 | if otherloc == loc: |
| 436 | return i |
| 437 | values.append(entry.frame.f_locals) |
| 438 | return None |
| 439 | |
| 440 | |
| 441 | E = TypeVar("E", bound=BaseException, covariant=True) |