diff --git a/Lib/inspect.py b/Lib/inspect.py index 675714dc8b3f70..c8211833dd0831 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1078,7 +1078,8 @@ def get_lineno(self): # First, let's see if there are any method definitions for member in self.cls.__dict__.values(): - if isinstance(member, types.FunctionType): + if (isinstance(member, types.FunctionType) and + member.__module__ == self.cls.__module__): for lineno, end_lineno in self.lineno_found: if lineno <= member.__code__.co_firstlineno <= end_lineno: return lineno diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 33a593f3591d68..3fbfc073255532 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -15,6 +15,7 @@ import shutil import sys import types +import tempfile import textwrap import unicodedata import unittest @@ -963,6 +964,33 @@ def test_nested_class_definition_inside_function(self): self.assertSourceEqual(mod2.cls213, 218, 222) self.assertSourceEqual(mod2.cls213().func219(), 220, 221) + def test_class_with_method_from_other_module(self): + with tempfile.TemporaryDirectory() as tempdir: + with open(os.path.join(tempdir, 'inspect_actual%spy' % os.extsep), + 'w', encoding='utf-8') as f: + f.write(textwrap.dedent(""" + import inspect_other + class A: + def f(self): + pass + class A: + def f(self): + pass # correct one + A.f = inspect_other.A.f + """)) + + with open(os.path.join(tempdir, 'inspect_other%spy' % os.extsep), + 'w', encoding='utf-8') as f: + f.write(textwrap.dedent(""" + class A: + def f(self): + pass + """)) + + with DirsOnSysPath(tempdir): + import inspect_actual + self.assertIn("correct", inspect.getsource(inspect_actual.A)) + @unittest.skipIf( support.is_emscripten or support.is_wasi, "socket.accept is broken"