summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorTal Einat <taleinat+github@gmail.com>2018-08-26 11:44:53 +0300
committerGitHub <noreply@github.com>2018-08-26 11:44:53 +0300
commit491740f116755e220135e596ec802ea3a0f65596 (patch)
tree8e3054260962955ca6947e026b82a8787aad6214 /Lib
parent032e85f3fb6d2e6668d4e860b40525ed6cb8dd69 (diff)
downloadcpython-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.py11
-rw-r--r--Lib/test/inspect_fodder.py6
-rw-r--r--Lib/test/test_inspect.py15
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()