diff options
-rw-r--r-- | Lib/inspect.py | 7 | ||||
-rw-r--r-- | Lib/test/test_inspect.py | 15 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
3 files changed, 24 insertions, 1 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py index 5344893a43..8f79bc3441 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -440,7 +440,9 @@ def getmodulename(path): if info: return info[0] def getsourcefile(object): - """Return the Python source file an object was defined in, if it exists.""" + """Return the filename that can be used to locate an object's source. + Return None if no way can be identified to get the source. + """ filename = getfile(object) if string.lower(filename[-4:]) in ('.pyc', '.pyo'): filename = filename[:-4] + '.py' @@ -453,6 +455,9 @@ def getsourcefile(object): # only return a non-existent filename if the module has a PEP 302 loader if hasattr(getmodule(object, filename), '__loader__'): return filename + # or it is in the linecache + if filename in linecache.cache: + return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index aaa15f881a..08630a59f7 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -3,6 +3,7 @@ import sys import types import unittest import inspect +import linecache import datetime from UserList import UserList from UserDict import UserDict @@ -274,6 +275,11 @@ class TestRetrievingSourceCode(GetSourceBase): def test_getsourcefile(self): self.assertEqual(inspect.getsourcefile(mod.spam), modfile) self.assertEqual(inspect.getsourcefile(git.abuse), modfile) + fn = "_non_existing_filename_used_for_sourcefile_test.py" + co = compile("None", fn, "exec") + self.assertEqual(inspect.getsourcefile(co), None) + linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) + self.assertEqual(inspect.getsourcefile(co), fn) def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) @@ -372,6 +378,15 @@ class TestBuggyCases(GetSourceBase): self.assertRaises(IOError, inspect.getsource, unicodedata) self.assertRaises(IOError, inspect.findsource, unicodedata) + def test_findsource_code_in_linecache(self): + lines = ["x=1"] + co = compile(lines[0], "_dynamically_created_file", "exec") + self.assertRaises(IOError, inspect.findsource, co) + self.assertRaises(IOError, inspect.getsource, co) + linecache.cache[co.co_filename] = (1, None, lines, co.co_filename) + self.assertEquals(inspect.findsource(co), (lines,0)) + self.assertEquals(inspect.getsource(co), lines[0]) + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] @@ -26,6 +26,9 @@ Core and Builtins Library ------- +- Issue #8720: fix regression caused by fix for #4050 by making getsourcefile + smart enough to find source files in the linecache. + - Issue #8986: math.erfc was incorrectly raising OverflowError for values between -27.3 and -30.0 on some platforms. |