(self, frame)
| 468 | return result |
| 469 | |
| 470 | def file_module_function_of(self, frame): |
| 471 | code = frame.f_code |
| 472 | filename = code.co_filename |
| 473 | if filename: |
| 474 | modulename = _modname(filename) |
| 475 | else: |
| 476 | modulename = None |
| 477 | |
| 478 | funcname = code.co_name |
| 479 | clsname = None |
| 480 | if code in self._caller_cache: |
| 481 | if self._caller_cache[code] is not None: |
| 482 | clsname = self._caller_cache[code] |
| 483 | else: |
| 484 | self._caller_cache[code] = None |
| 485 | ## use of gc.get_referrers() was suggested by Michael Hudson |
| 486 | # all functions which refer to this code object |
| 487 | funcs = [f for f in gc.get_referrers(code) |
| 488 | if inspect.isfunction(f)] |
| 489 | # require len(func) == 1 to avoid ambiguity caused by calls to |
| 490 | # new.function(): "In the face of ambiguity, refuse the |
| 491 | # temptation to guess." |
| 492 | if len(funcs) == 1: |
| 493 | dicts = [d for d in gc.get_referrers(funcs[0]) |
| 494 | if isinstance(d, dict)] |
| 495 | if len(dicts) == 1: |
| 496 | classes = [c for c in gc.get_referrers(dicts[0]) |
| 497 | if hasattr(c, "__bases__")] |
| 498 | if len(classes) == 1: |
| 499 | # ditto for new.classobj() |
| 500 | clsname = classes[0].__name__ |
| 501 | # cache the result - assumption is that new.* is |
| 502 | # not called later to disturb this relationship |
| 503 | # _caller_cache could be flushed if functions in |
| 504 | # the new module get called. |
| 505 | self._caller_cache[code] = clsname |
| 506 | if clsname is not None: |
| 507 | funcname = "%s.%s" % (clsname, funcname) |
| 508 | |
| 509 | return filename, modulename, funcname |
| 510 | |
| 511 | def globaltrace_trackcallers(self, frame, why, arg): |
| 512 | """Handler for call events. |
no test coverage detected