def get_module_of_previous_context(): current_ctx = inspect.currentframe() while True: current_ctx = current_ctx.f_back frameinfo_args = (current_ctx, ) + inspect.getframeinfo(current_ctx, 1) frameinfo = inspect.FrameInfo(*frameinfo_args) module = inspect.getmodule(frameinfo[0]) if module and not module.__name__.startswith("requre"): return module
def new_inspect_stack(*args, **kwargs): stack = old_inspect_stack(*args, **kwargs) # The top frame of the stack is for the new_inspect_stack function itself. stack.pop(0) if is_tester_frame(stack[1].frame): # Insert a frame that mimics the top level of the Python shell. frame = inspect.FrameInfo(frame=None, filename='<stdin>', lineno=1, function='<module>', code_context=None, index=None) stack.insert(1, frame) return stack
def get_frameinfo(depth=0, context=1): """ Finds the frame at `depth` and builds a `inspect.FrameInfo` from it. Executes 10 times faster than `inspect.stack()[depth]` if depth is superior to 1, else only 2 times. Handles negative `depth` by returning the current frame from the caller's perspective, just like `sys._getframe()` does. Examples: ```python import inspect from flashback.debugging import get_frameinfo assert get_frameinfo() == inspect.stack()[0] def dummy_func(): return get_frameinfo() frameinfo = dummy_func() assert frameinfo.function == 'dummy_func' ``` Params: - `depth (int)` the depth at which to find the frame - `context (int)` the number of lines surrounding the frame to use in the traceback Returns: - `inspect.FrameInfo` the FrameInfo object for the frame Raises: - `ValueError` if `depth` is greater than the length of the call stack """ # Could use `sys._getframe(1)` but safer to go through its wrapper frame = inspect.currentframe() # Skips the actual current frame (the execution of get_frame()) depth = depth + 1 if depth > -1 else 1 for _ in range(depth): if frame is None: raise ValueError('call stack is not deep enough') frame = frame.f_back if frame is None: raise ValueError('call stack is not deep enough') frameinfo = (frame,) + inspect.getframeinfo(frame, context) return inspect.FrameInfo(*frameinfo)
def frames(self) -> FrameCollection: if self._frames is not None: return self._frames self._frames = FrameCollection() tb = self._exception.__traceback__ while tb: frame_info = inspect.getframeinfo(tb) self._frames.append( Frame(inspect.FrameInfo(tb.tb_frame, *frame_info))) tb = tb.tb_next return self._frames
def _get_outer_frames(frame, context=1, full_impl=True): """Get a list of records for a frame and all higher (calling) frames. Each record contains a frame object, filename, line number, function name, a list of lines of context, and index within the context.""" # framelist = [] while frame: if full_impl: frameinfo = (frame, ) + inspect.getframeinfo(frame, context) yield inspect.FrameInfo(*frameinfo) else: yield frame, None if frame == frame.f_back: raise IndexError frame = frame.f_back
def invalid(): _ = get_module_impl(inspect.FrameInfo(frame=frm, filename=fil, lineno=lin, function=fun, code_context=con, index=idx))
def test_frame_with_no_context_should_return_empty_line(): frame = Frame( inspect.FrameInfo(None, "filename.py", 123, "function", None, 3)) assert "" == frame.line