def start(self, filename): """Starts tracing a file.""" files = self.files if len(files) == 0: self.prev_tracer = sys.gettrace() files.add(normabspath(filename)) sys.settrace(self.trace) curr = inspect.currentframe() for frame, fname, *_ in getouterframes(curr, context=0): if normabspath(fname) in files: frame.f_trace = self.trace
def stop(self, filename): """Stops tracing a file.""" filename = normabspath(filename) self.files.discard(filename) if len(self.files) == 0: sys.settrace(self.prev_tracer) curr = inspect.currentframe() for frame, fname, *_ in getouterframes(curr, context=0): if normabspath(fname) == filename: frame.f_trace = self.prev_tracer self.prev_tracer = DefaultNotGiven
def _find_caller(args): """Somewhat hacky method of finding the __file__ based on the line executed.""" re_line = re.compile(r'[^;\s|&<>]+\s+' + r'\s+'.join(args)) curr = inspect.currentframe() for _, fname, lineno, _, lines, _ in getouterframes(curr, context=1)[3:]: if lines is not None and re_line.search(lines[0]) is not None: return fname elif lineno == 1 and re_line.search(linecache.getline(fname, lineno)) is not None: # There is a bug in CPython such that getouterframes(curr, context=1) # will actually return the 2nd line in the code_context field, even though # line number is itself correct. We manually fix that in this branch. return fname else: msg = ('xonsh: warning: __file__ name could not be found. You may be ' 'trying to trace interactively. Please pass in the file names ' 'you want to trace explicitly.') print(msg, file=sys.stderr)
def test_getouterframes(): """Just test that this works.""" curr = inspect.currentframe() getouterframes(curr, context=0)