Make getsourcefile() succeed even if the filename doesn't end in '.py' --
as long as the filename also doesn't end in a suffix that indicates a binary file (according to the flags in imp.get_suffixes()). Shrink try...except clauses and replace some of them with explicit checks.
This commit is contained in:
parent
9054344d14
commit
4eb0c003f8
|
@ -197,20 +197,25 @@ def getsourcefile(object):
|
||||||
filename = getfile(object)
|
filename = getfile(object)
|
||||||
if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
|
if string.lower(filename[-4:]) in ['.pyc', '.pyo']:
|
||||||
filename = filename[:-4] + '.py'
|
filename = filename[:-4] + '.py'
|
||||||
if string.lower(filename[-3:]) == '.py' and os.path.exists(filename):
|
for suffix, mode, kind in imp.get_suffixes():
|
||||||
|
if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix:
|
||||||
|
# Looks like a binary file. We want to only return a text file.
|
||||||
|
return None
|
||||||
|
if os.path.exists(filename):
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def getabsfile(object):
|
def getabsfile(object):
|
||||||
"""Return an absolute path to the source file or compiled file for an object.
|
"""Return an absolute path to the source or compiled file for an object.
|
||||||
|
|
||||||
The idea is for each object to have a unique origin, so this routine normalizes
|
The idea is for each object to have a unique origin, so this routine
|
||||||
the result as much as possible."""
|
normalizes the result as much as possible."""
|
||||||
return os.path.normcase(os.path.abspath(getsourcefile(object) or getfile(object)))
|
return os.path.normcase(
|
||||||
|
os.path.abspath(getsourcefile(object) or getfile(object)))
|
||||||
|
|
||||||
modulesbyfile = {}
|
modulesbyfile = {}
|
||||||
|
|
||||||
def getmodule(object):
|
def getmodule(object):
|
||||||
"""Try to guess which module an object was defined in."""
|
"""Return the module an object was defined in, or None if not found."""
|
||||||
if isclass(object):
|
if isclass(object):
|
||||||
return sys.modules.get(object.__module__)
|
return sys.modules.get(object.__module__)
|
||||||
try:
|
try:
|
||||||
|
@ -225,15 +230,15 @@ def getmodule(object):
|
||||||
if modulesbyfile.has_key(file):
|
if modulesbyfile.has_key(file):
|
||||||
return sys.modules[modulesbyfile[file]]
|
return sys.modules[modulesbyfile[file]]
|
||||||
main = sys.modules['__main__']
|
main = sys.modules['__main__']
|
||||||
try:
|
if hasattr(main, object.__name__):
|
||||||
mainobject = getattr(main, object.__name__)
|
mainobject = getattr(main, object.__name__)
|
||||||
if mainobject is object: return main
|
if mainobject is object:
|
||||||
except AttributeError: pass
|
return main
|
||||||
builtin = sys.modules['__builtin__']
|
builtin = sys.modules['__builtin__']
|
||||||
try:
|
if hasattr(builtin, object.__name__):
|
||||||
builtinobject = getattr(builtin, object.__name__)
|
builtinobject = getattr(builtin, object.__name__)
|
||||||
if builtinobject is object: return builtin
|
if builtinobject is object:
|
||||||
except AttributeError: pass
|
return builtin
|
||||||
|
|
||||||
def findsource(object):
|
def findsource(object):
|
||||||
"""Return the entire source file and starting line number for an object.
|
"""Return the entire source file and starting line number for an object.
|
||||||
|
@ -244,10 +249,10 @@ def findsource(object):
|
||||||
is raised if the source code cannot be retrieved."""
|
is raised if the source code cannot be retrieved."""
|
||||||
try:
|
try:
|
||||||
file = open(getsourcefile(object))
|
file = open(getsourcefile(object))
|
||||||
lines = file.readlines()
|
|
||||||
file.close()
|
|
||||||
except (TypeError, IOError):
|
except (TypeError, IOError):
|
||||||
raise IOError, 'could not get source code'
|
raise IOError, 'could not get source code'
|
||||||
|
lines = file.readlines()
|
||||||
|
file.close()
|
||||||
|
|
||||||
if ismodule(object):
|
if ismodule(object):
|
||||||
return lines, 0
|
return lines, 0
|
||||||
|
@ -269,11 +274,9 @@ def findsource(object):
|
||||||
if isframe(object):
|
if isframe(object):
|
||||||
object = object.f_code
|
object = object.f_code
|
||||||
if iscode(object):
|
if iscode(object):
|
||||||
try:
|
if not hasattr(object, 'co_firstlineno'):
|
||||||
lnum = object.co_firstlineno - 1
|
|
||||||
except AttributeError:
|
|
||||||
raise IOError, 'could not find function definition'
|
raise IOError, 'could not find function definition'
|
||||||
else:
|
lnum = object.co_firstlineno - 1
|
||||||
while lnum > 0:
|
while lnum > 0:
|
||||||
if string.split(lines[lnum])[:1] == ['def']: break
|
if string.split(lines[lnum])[:1] == ['def']: break
|
||||||
lnum = lnum - 1
|
lnum = lnum - 1
|
||||||
|
@ -282,7 +285,7 @@ def findsource(object):
|
||||||
def getcomments(object):
|
def getcomments(object):
|
||||||
"""Get lines of comments immediately preceding an object's source code."""
|
"""Get lines of comments immediately preceding an object's source code."""
|
||||||
try: lines, lnum = findsource(object)
|
try: lines, lnum = findsource(object)
|
||||||
except: return None
|
except IOError: return None
|
||||||
|
|
||||||
if ismodule(object):
|
if ismodule(object):
|
||||||
# Look for a comment block at the top of the file.
|
# Look for a comment block at the top of the file.
|
||||||
|
@ -574,12 +577,13 @@ def getframeinfo(frame, context=1):
|
||||||
start = lineno - 1 - context/2
|
start = lineno - 1 - context/2
|
||||||
try:
|
try:
|
||||||
lines, lnum = findsource(frame)
|
lines, lnum = findsource(frame)
|
||||||
|
except IOError:
|
||||||
|
lines = index = None
|
||||||
|
else:
|
||||||
start = max(start, 1)
|
start = max(start, 1)
|
||||||
start = min(start, len(lines) - context)
|
start = min(start, len(lines) - context)
|
||||||
lines = lines[start:start+context]
|
lines = lines[start:start+context]
|
||||||
index = lineno - 1 - start
|
index = lineno - 1 - start
|
||||||
except IOError:
|
|
||||||
lines = index = None
|
|
||||||
else:
|
else:
|
||||||
lines = index = None
|
lines = index = None
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue