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:
Ka-Ping Yee 2001-03-02 05:50:34 +00:00
parent 9054344d14
commit 4eb0c003f8
1 changed files with 29 additions and 25 deletions

View File

@ -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,20 +274,18 @@ 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
return lines, lnum return lines, lnum
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