2

For debugging purposes I would like to get the source code of the function that has called my function. So in the following situation:

def calling_func():
    x = 123
    y = x + 1
    myfunc()

def myfunc():
    calling_source = f()

I would like a function f, such that calling_source becomes the string

"""
x = 123
y = x + 1
myfunc()
"""

Does such a function exist? I'm guessing that this might be possible with something like sys._current_frames and the inspect module.

MRocklin
  • 55,641
  • 23
  • 163
  • 235
  • How about https://stackoverflow.com/questions/2654113/how-to-get-the-callers-method-name-in-the-called-method + https://stackoverflow.com/questions/427453/how-can-i-get-the-source-code-of-a-python-function ? – AMC Feb 10 '20 at 01:03
  • 1
    you need the source code programmatically as a `str` object? Why not just use a modern debugger in the text editor of your choice with break points etc? Then you can step through the call stack with the source code in front of you. – juanpa.arrivillaga Feb 10 '20 at 01:04
  • I'm voting to close for duplication, but apart from that: don't write your own debugger, that's generally a really bad idea, unless you have some crazy use case where that makes sense (or you're developing an editor / IDE, but then I wouldn't expect you here asking these questions). – Grismar Feb 10 '20 at 01:07
  • 1
    I appreciate the advice to use a debugger. I write tools for developers. I know what I'm doing here. – MRocklin Feb 10 '20 at 02:04
  • @MadPhysicist I would appreciate it if you would keep commentary on Stack Overflow civil and constructive – MRocklin Feb 10 '20 at 02:14
  • 2
    Fair point. Question is valid regardless of your motives and background. – Mad Physicist Feb 10 '20 at 04:07
  • I disagree with closing this question. The referred to question is about getting the source of a Python function. I'm looking for the source of a Python frame. – MRocklin Feb 10 '20 at 04:27

2 Answers2

4
import sys
import inspect

def called():
    print(inspect.getsource(sys._getframe().f_back))

def caller():
    called()
    x = 123     # Some example code
    y = x + 1

caller()

Output:

def caller():
    called()
    x = 123     # Some example code
    y = x + 1

inspect.getsource(object) takes an object as parameter and returns the source code as string.

Pingmader
  • 61
  • 5
1
In [1]: import inspect                                                          

In [2]: def calling_func(): 
   ...:     x = 123 
   ...:     y = x + 1 
   ...:     text = f() 
   ...:     print(text) 
   ...:                                                                         

In [3]: def f() -> str: 
   ...:     frame = inspect.currentframe() 
   ...:     frame = frame.f_back  # go up one in the stack 
   ...:     text = inspect.getsource(frame) 
   ...:     return text 
   ...:                                                                         

In [4]: calling_func()                                                          
def calling_func():
    x = 123
    y = x + 1
    text = f()
    print(text)
MRocklin
  • 55,641
  • 23
  • 163
  • 235