@@ -169,7 +169,7 @@ def getdoc(object):
169169 return string .join (lines , '\n ' )
170170
171171def getfile (object ):
172- """Try to guess which (text or binary) file an object was defined in."""
172+ """Work out which source or compiled file an object was defined in."""
173173 if ismodule (object ):
174174 if hasattr (object , '__file__' ):
175175 return object .__file__
@@ -192,22 +192,36 @@ def getfile(object):
192192 raise TypeError , 'arg is not a module, class, method, ' \
193193 'function, traceback, frame, or code object'
194194
195+ def getsourcefile (object ):
196+ """Return the Python source file an object was defined in, if it exists."""
197+ filename = getfile (object )
198+ if string .lower (filename [- 4 :]) in ['.pyc' , '.pyo' ]:
199+ filename = filename [:- 4 ] + '.py'
200+ if string .lower (filename [- 3 :]) == '.py' and os .path .exists (filename ):
201+ return filename
202+
203+ def getabsfile (object ):
204+ """Return an absolute path to the source file or compiled file for an object.
205+
206+ The idea is for each object to have a unique origin, so this routine normalizes
207+ the result as much as possible."""
208+ return os .path .normcase (os .path .abspath (getsourcefile (object ) or getfile (object )))
209+
195210modulesbyfile = {}
196211
197212def getmodule (object ):
198213 """Try to guess which module an object was defined in."""
199214 if isclass (object ):
200215 return sys .modules .get (object .__module__ )
201216 try :
202- file = os . path . abspath ( getsourcefile ( object ) )
217+ file = getabsfile ( object )
203218 except TypeError :
204219 return None
205220 if modulesbyfile .has_key (file ):
206221 return sys .modules [modulesbyfile [file ]]
207222 for module in sys .modules .values ():
208223 if hasattr (module , '__file__' ):
209- modulesbyfile [
210- os .path .abspath (getsourcefile (module ))] = module .__name__
224+ modulesbyfile [getabsfile (module )] = module .__name__
211225 if modulesbyfile .has_key (file ):
212226 return sys .modules [modulesbyfile [file ]]
213227 main = sys .modules ['__main__' ]
@@ -221,13 +235,6 @@ def getmodule(object):
221235 if builtinobject is object : return builtin
222236 except AttributeError : pass
223237
224- def getsourcefile (object ):
225- """Try to guess which Python source file an object was defined in."""
226- filename = getfile (object )
227- if filename [- 4 :] == '.pyc' :
228- filename = filename [:- 4 ] + '.py'
229- return filename
230-
231238def findsource (object ):
232239 """Return the entire source file and starting line number for an object.
233240
@@ -571,7 +578,7 @@ def getframeinfo(frame, context=1):
571578 start = min (start , len (lines ) - context )
572579 lines = lines [start :start + context ]
573580 index = lineno - 1 - start
574- except :
581+ except IOError :
575582 lines = index = None
576583 else :
577584 lines = index = None
0 commit comments