From 7de29687f22fff5c38ca252de4167e043b28e470 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 8 Dec 2014 18:00:25 -0500 Subject: inspect: Fix getsource() to load updated source of reloaded module Issue #1218234. Initial patch by Berker Peksag. --- 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 index 530f240..1641824 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -652,11 +652,17 @@ def findsource(object): 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 "" 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 index 66d3fab..fc3bf07 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -12,6 +12,7 @@ import re import shutil import sys import types +import textwrap import unicodedata import unittest import unittest.mock @@ -27,6 +28,8 @@ from test.script_helper import assert_python_ok, assert_python_failure 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 @@ class TestMain(unittest.TestCase): 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 @@ def test_main(): 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 index 357f4aa..6c0c1f2 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -39,6 +39,9 @@ Core and Builtins 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. -- cgit v0.12