I'm running some custom Python code in Sphinx and need to get the path to the caller module. (Essentially this is the caller's __file__
object; I need to interpret a filename relative to this location.)
I can get the filename from inspect.stack()
as per How to use inspect to get the caller's info from callee in Python?, but apparently I need to interpret this filename in the context of the Python startup directory. (Sometimes inspect.stack()[k][1]
is an absolute path but sometimes it is a relative path like conf.py
; the inspect.stack()
function doesn't seem to document this but unutbu claims in a comment that it is relative to the Python startup directory. )
Sphinx does some unintentionally evil things like this comment:
# This file is execfile()d with the current directory set to its
# containing dir.
so os.path.abspath(filename)
doesn't work, and
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('extensions'))
so sys.path[0]
is corrupted by the time my code gets to it.
How do I find the startup directory in Python, if sys.path
has been modified?
Or is there another way to get the path to the caller module?
If I run Jean-François Fabre's answer
for file,line,w1,w2 in traceback.extract_stack():
sys.stdout.write(' File "{}", line {}, in {}\n'.format(file,line,w1))
I get this:
File "c:\app\python\anaconda\1.6.0\Scripts\sphinx-build-script.py", line 5, in <module>
File "c:\app\python\anaconda\1.6.0\lib\site-packages\Sphinx-1.4.1-py2.7.egg\sphinx\__init__.py", line 51, in main
File "c:\app\python\anaconda\1.6.0\lib\site-packages\Sphinx-1.4.1-py2.7.egg\sphinx\__init__.py", line 92, in build_main
File "c:\app\python\anaconda\1.6.0\lib\site-packages\Sphinx-1.4.1-py2.7.egg\sphinx\cmdline.py", line 243, in main
File "c:\app\python\anaconda\1.6.0\lib\site-packages\Sphinx-1.4.1-py2.7.egg\sphinx\application.py", line 155, in __init__
File "conf.py", line 512, in setup
[more lines elided, the conf.py is the one that matters]
so the problem is that I need to find the path to conf.py
but the current directory has been changed by Sphinx so I can't just do os.path.abspath(caller_filename)