1

I want to make a function that can determine the source code of how it was called. I'm aware of how to do this generally with the inspect module. For example, this question, works well and provides my desired output in the lines variable as shown below:

def hello(x):
   frame,filename,line_number,function_name,lines,index=\
       inspect.getouterframes(inspect.currentframe())[1]
   print(frame,filename,line_number,function_name,lines,index)

The problem is that this solution doesn't work in an interactive command line session. For example, from a command line, the result looks like:

>>> y = hello(7)
(<frame object at 0x01ECA9E8>, '<stdin>', 1, '<module>', None, None)

The problem is that the source file is '<stdin>', so the lines variable is None. How can I access the calling line to find the result containing the string y = hello(7) during an interactive session?

Community
  • 1
  • 1
TJD
  • 11,800
  • 1
  • 26
  • 34
  • 1
    You can't, because the interactive session doesn't keep track of the lines typed into it. If you're willing to require `ipython`, there's probably a way to do it there. Or you can write your own wrapper around the interactive session that just keeps track of the lines read into `stdin` and passes them through (that may be incorrect, but you can find the correct details through trial and error), you could index into that. – abarnert Nov 02 '12 at 22:59

1 Answers1

2

It may not be possible, as @abarnert says. There are at least partial workarounds, however.

Getting source code lines isn't the biggest problem; modules like readline keep track of them. Interactive Python and iPython expose their lines slightly differently (sigh), but that too can be equalized. (My show package, for example, does this; its linecacher module puts a veneer on to equalize source access for normal Python and the different interactive flavors.)

The bigger problem is that, even once you have the source code, inspect doesn't provide legitimate line numbers (e.g. inspect.currentframe().f_back.f_lineno works great in normal code, but gives values like 1 or the point of the call in <stdin> when called interactively.)

But I'm not quite ready to call it impossible. Based on tracebacks generated by interactive Python and iPython, it appears that there may be sufficient information available to reconstruct "where did this call come from?" How much effort that would take, and how robust the answers would be...those are open questions.

Community
  • 1
  • 1
Jonathan Eunice
  • 21,653
  • 6
  • 75
  • 77