I need to get the source of a function 'get_id' and inspect.getsource() is returning the source of the function 'update_creds' and I have no idea why
Some specifics about the environment: Its running on Splunks SOAR, which looking at the stack trace seems like it is running a wrapper program to fetch, decode, execute the script so just asking inspect to find the source doesn't seem to work unless I manually import the file into itself.
Here's the code I am debugging:
def update_creds(**kwargs):
print("update_creds")
# Function header I cannot touch
def get_id(**kwargs):
# inspect.stack()[0][3] gets the name of the function we are currently in
exec(get_new_return(function=inspect.stack()[0][3]))
return
# Automatically generated code I cannot touch
phantom.act("old_parameter","other_parameters_that_change")
return
# Function header I cannot touch
def get_function_source(**kwargs):
import inspect
import re
import sys
# We have to add the git repo to the system path so we can import the file
sys.path.insert(0, '/scm/git/')
# Get the file name from __file__ (its formatted within angle brackets, so we get rid of them
source=__import__(re.sub(r'(<|>)','',__file__))
# use eval to specifially refer to this files function object.
# using debug comments, the eval does indeed refer to the correct object I want the source from
# However, the return of inspect.getsource() gives me the source of another function
function_source=inspect.getsource(eval("source."+kwargs["function"]))
generated_code=re.findall(r'phantom.act\((.*)\)', function_source)[-1]
return generated_code.replace("old_parameter", "new_parameter")
get_id()
If you really want to know why I am doing this, the environment uses code blocks to generate python code, specifically function definitions and the final function call to continue execution. However, I need to add a parameter to the next function call, so I am using inspect.getsource() to get the final function call, add the parameter, call it, and do an early return.
I tried following where it loses reference to the correct function, which seems to be when inspect.getsource() is called. I am expecting the source of the 'get_id' function instead of the 'update_creds' function.
Looking into how getsource works, I thought it might have something to do with the name of the function, but the names do not have anything in common from what I can see. The only other thing I can think of would be if getsource refers to line numbers and its incorrectly using the line number from one file to another, but I would have no idea how to force inspect to make sure its referring to the same file
Edit: Added more to the code block for more context. In adding context I noticed that update_creds is the function right above get_id, so its almost as if inspect.getsource() needs to go down one more function definition, but I don't know if this is a one-off or if it will always be off by one. And if it is always off by one, how would I get getsource to give me the next function?
In your code,
get_id()is never called, so at no time will it be in the stack trace.Aside from that, it looks like the answer is in your code's comment;
inspect.stack()[0][3])will evaluate to 'update_creds', because that's the function you are in when you call it. So, when you callget_new_return(), thefunctionarg will be set to 'update_creds'. As a result,get_new_return()is getting the source forupdate_creds()