[issue4375] inspect.getsource doesn't work with PYTHONPATH and source compiled from a different dir

Erick Tryzelaar report at bugs.python.org
Fri Nov 21 10:53:24 CET 2008


New submission from Erick Tryzelaar <idadesub at users.sourceforge.net>:

I'm running into a similar problem as Jean-Paul in:

http://bugs.python.org/issue4223

But the patch in it doesn't work for me. My issue is also with files 
compiled already with python3.0, but then being accessed from a 
different location using PYTHONPATH. Here's a full example of the 
problem:

mkdir dir1
mkdir dir1/foo
mkdir dir2
echo 'def f(): pass' >  dir1/foo/__init__.py
cd dir1
python3.0 -c "import foo"
cd ../dir2
python3.0 -c "import inspect, sys; sys.path.append('../dir1'); import 
foo; print(inspect.getsource(foo.f))"

Which errors out with:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File 
"/opt/local/Library/Frameworks/Python.framework/Versions/3.0/lib/python3
.0/inspect.py", line 691, in getsource
    lines, lnum = getsourcelines(object)
  File 
"/opt/local/Library/Frameworks/Python.framework/Versions/3.0/lib/python3
.0/inspect.py", line 680, in getsourcelines
    lines, lnum = findsource(object)
  File 
"/opt/local/Library/Frameworks/Python.framework/Versions/3.0/lib/python3
.0/inspect.py", line 528, in findsource
    raise IOError('could not get source code')
IOError: could not get source code


If I instrument inspect, it looks like what's happening is that 
linecache is being passed f.__code__.co_filename. However with the 
sys.path manipulation, that filename is baked into the .pyc file as 
"foo/__init__.py". This confuses linecache which can't find the file. 
Here's one suggestion of a fix.

--- /tmp/inspect.py	2008-11-21 01:34:56.000000000 -0800
+++ /opt/local/lib/python3.0/inspect.py	2008-11-21 01:35:28.000000000 -
0800
@@ -518,6 +518,7 @@
     is raised if the source code cannot be retrieved."""
     file = getsourcefile(object) or getfile(object)
     module = getmodule(object, file)
+    file = getsourcefile(module) or getfile(file)
     if module:
         lines = linecache.getlines(file, module.__dict__)
     else:

It looks like in most situations the module has an accurate __file__ 
that's updated from PYTHONPATH. I'm not sure if this works in every 
situation, but this, along with the other patch, work together to get 
the source printing working.

----------
components: Library (Lib)
messages: 76170
nosy: erickt
severity: normal
status: open
title: inspect.getsource doesn't work with PYTHONPATH and source compiled from a different dir
type: behavior
versions: Python 3.0

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue4375>
_______________________________________


More information about the Python-bugs-list mailing list