[Python-checkins] cpython (3.4): inspect: Fix getsource() to load updated source of reloaded module

yury.selivanov python-checkins at python.org
Tue Dec 9 00:01:53 CET 2014


https://hg.python.org/cpython/rev/e52d8e888df1
changeset:   93793:e52d8e888df1
branch:      3.4
parent:      93789:7253417efd1e
user:        Yury Selivanov <yselivanov at sprymix.com>
date:        Mon Dec 08 18:00:25 2014 -0500
summary:
  inspect: Fix getsource() to load updated source of reloaded module

Issue #1218234. Initial patch by Berker Peksag.

files:
  Lib/inspect.py           |  16 +++++++++----
  Lib/test/test_inspect.py |  33 +++++++++++++++++++++++++++-
  Misc/NEWS                |   3 ++
  3 files changed, 46 insertions(+), 6 deletions(-)


diff --git a/Lib/inspect.py b/Lib/inspect.py
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -652,11 +652,17 @@
     in the file and the line number indexes a line in that list.  An OSError
     is raised if the source code cannot be retrieved."""
 
-    file = getfile(object)
-    sourcefile = getsourcefile(object)
-    if not sourcefile and file[:1] + file[-1:] != '<>':
-        raise OSError('source code not available')
-    file = sourcefile if sourcefile else file
+    file = getsourcefile(object)
+    if file:
+        # Invalidate cache if needed.
+        linecache.checkcache(file)
+    else:
+        file = getfile(object)
+        # Allow filenames in form of "<something>" to pass through.
+        # `doctest` monkeypatches `linecache` module to enable
+        # inspection, so let `linecache.getlines` to be called.
+        if not (file.startswith('<') and file.endswith('>')):
+            raise OSError('source code not available')
 
     module = getmodule(object, file)
     if module:
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -12,6 +12,7 @@
 import shutil
 import sys
 import types
+import textwrap
 import unicodedata
 import unittest
 import unittest.mock
@@ -27,6 +28,8 @@
 from test import inspect_fodder as mod
 from test import inspect_fodder2 as mod2
 
+from test.test_import import _ready_to_import
+
 
 # Functions tested in this suite:
 # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
@@ -3087,6 +3090,34 @@
         self.assertEqual(err, b'')
 
 
+class TestReload(unittest.TestCase):
+
+    src_before = textwrap.dedent("""\
+def foo():
+    print("Bla")
+    """)
+
+    src_after = textwrap.dedent("""\
+def foo():
+    print("Oh no!")
+    """)
+
+    def assertInspectEqual(self, path, source):
+        inspected_src = inspect.getsource(source)
+        with open(path) as src:
+            self.assertEqual(
+                src.read().splitlines(True),
+                inspected_src.splitlines(True)
+            )
+
+    def test_getsource_reload(self):
+        # see issue 1218234
+        with _ready_to_import('reload_bug', self.src_before) as (name, path):
+            module = importlib.import_module(name)
+            self.assertInspectEqual(path, module)
+            with open(path, 'w') as src:
+                src.write(self.src_after)
+            self.assertInspectEqual(path, module)
 
 
 def test_main():
@@ -3097,7 +3128,7 @@
         TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState,
         TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
         TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars,
-        TestUnwrap, TestMain
+        TestUnwrap, TestMain, TestReload
     )
 
 if __name__ == "__main__":
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,9 @@
 Library
 -------
 
+- Issue #1218234: Fix inspect.getsource() to load updated source of
+  reloaded module. Initial patch by Berker Peksag.
+
 - Issue #22959: In the constructor of http.client.HTTPSConnection, prefer the
   context's check_hostname attribute over the *check_hostname* parameter.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list