def get_python_file_from_previous_stack_frame():
    'inspect.stack() lets us introspect the call stack; inspect.stack()[1] is the previous\n    stack frame.\n\n    In Python < 3.5, this is just a tuple, of which the python file of the previous frame is the 1st\n    element.\n\n    In Python 3.5+, this is a FrameInfo namedtuple instance; the python file of the previous frame\n    remains the 1st element.\n    '
    previous_stack_frame = inspect.stack(0)[2]
    if ((sys.version_info.major == 3) and (sys.version_info.minor >= 5)):
        check.inst(previous_stack_frame, inspect.FrameInfo)
    else:
        check.inst(previous_stack_frame, tuple)
    python_file = previous_stack_frame[1]
    return os.path.abspath(python_file)
inspect.stack() lets us introspect the call stack; inspect.stack()[1] is the previous
stack frame.

In Python < 3.5, this is just a tuple, of which the python file of the previous frame is the 1st
element.

In Python 3.5+, this is a FrameInfo namedtuple instance; the python file of the previous frame
remains the 1st element.
def get_python_file_from_previous_stack_frame():
    'inspect.stack() lets us introspect the call stack; inspect.stack()[1] is the previous\n    stack frame.\n\n    In Python < 3.5, this is just a tuple, of which the python file of the previous frame is the 1st\n    element.\n\n    In Python 3.5+, this is a FrameInfo namedtuple instance; the python file of the previous frame\n    remains the 1st element.\n    '
    previous_stack_frame = inspect.stack(0)[2]
    if ((sys.version_info.major == 3) and (sys.version_info.minor >= 5)):
        check.inst(previous_stack_frame, inspect.FrameInfo)
    else:
        check.inst(previous_stack_frame, tuple)
    python_file = previous_stack_frame[1]
    return os.path.abspath(python_file)