diff options
author | Tal Einat <taleinat+github@gmail.com> | 2018-08-26 11:44:53 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-26 11:44:53 +0300 |
commit | 491740f116755e220135e596ec802ea3a0f65596 (patch) | |
tree | 8e3054260962955ca6947e026b82a8787aad6214 /Lib | |
parent | 032e85f3fb6d2e6668d4e860b40525ed6cb8dd69 (diff) | |
download | cpython-git-491740f116755e220135e596ec802ea3a0f65596.tar.gz |
[2.7] bpo-6700: Fix inspect.getsourcelines for module level frames/tracebacks (GH-8864)
(cherry picked from commit 91cb298f811961277fd4cc4a32211899d48bedcb)
Co-authored-by: Vladimir Matveev <v2matveev@outlook.com>
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/inspect.py | 11 | ||||
-rw-r--r-- | Lib/test/inspect_fodder.py | 6 | ||||
-rw-r--r-- | Lib/test/test_inspect.py | 15 |
3 files changed, 28 insertions, 4 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py index 0a6cfd7951..cbced17373 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -688,8 +688,15 @@ def getsourcelines(object): raised if the source code cannot be retrieved.""" lines, lnum = findsource(object) - if ismodule(object): return lines, 0 - else: return getblock(lines[lnum:]), lnum + 1 + if istraceback(object): + object = object.tb_frame + + # for module or frame that corresponds to module, return all source lines + if (ismodule(object) or + (isframe(object) and object.f_code.co_name == "<module>")): + return lines, 0 + else: + return getblock(lines[lnum:]), lnum + 1 def getsource(object): """Return the text of the source code for an object. diff --git a/Lib/test/inspect_fodder.py b/Lib/test/inspect_fodder.py index 5c87ae6f82..548765c797 100644 --- a/Lib/test/inspect_fodder.py +++ b/Lib/test/inspect_fodder.py @@ -56,3 +56,9 @@ class ParrotDroppings: class FesteringGob(MalodorousPervert, ParrotDroppings): pass + +currentframe = inspect.currentframe() +try: + raise Exception() +except: + tb = sys.exc_info()[2] diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 7d09c6fa02..5063a30d22 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -209,7 +209,7 @@ class GetSourceBase(unittest.TestCase): def sourcerange(self, top, bottom): lines = self.source.split("\n") - return "\n".join(lines[top-1:bottom]) + "\n" + return "\n".join(lines[top-1:bottom]) + ("\n" if bottom else "") def assertSourceEqual(self, obj, top, bottom): self.assertEqual(inspect.getsource(obj), @@ -331,6 +331,16 @@ class TestRetrievingSourceCode(GetSourceBase): finally: linecache.getlines = getlines +class TestGettingSourceOfToplevelFrames(GetSourceBase): + fodderFile = mod + + def test_range_toplevel_frame(self): + self.maxDiff = None + self.assertSourceEqual(mod.currentframe, 1, None) + + def test_range_traceback_toplevel_frame(self): + self.assertSourceEqual(mod.tb, 1, None) + class TestDecorators(GetSourceBase): fodderFile = mod2 @@ -896,7 +906,8 @@ def test_main(): TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates, TestGetcallargsFunctions, TestGetcallargsFunctionsCellVars, - TestGetcallargsMethods, TestGetcallargsUnboundMethods) + TestGetcallargsMethods, TestGetcallargsUnboundMethods, + TestGettingSourceOfToplevelFrames) if __name__ == "__main__": test_main() |