diff -r bdde36cd9048 Lib/inspect.py --- a/Lib/inspect.py Mon Apr 14 10:28:58 2014 -0400 +++ b/Lib/inspect.py Mon Apr 14 18:40:20 2014 -0400 @@ -818,8 +818,20 @@ 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 ismodule(object): + return lines, 0 + elif iscode(object) or isroutine(object): + if isfunction(object): + code = object.__code__ + elif ismethod(object): + code = object.__func__.__code__ + else: + code = object + line_offsets = list(code.co_lnotab[1::2]) + end_line = sum(line_offsets) + lnum + 1 + return lines[lnum:end_line], lnum + 1 + else: + return getblock(lines[lnum:]), lnum + 1 def getsource(object): """Return the text of the source code for an object. diff -r bdde36cd9048 Lib/test/inspect_fodder2.py --- a/Lib/test/inspect_fodder2.py Mon Apr 14 10:28:58 2014 -0400 +++ b/Lib/test/inspect_fodder2.py Mon Apr 14 18:40:20 2014 -0400 @@ -109,3 +109,19 @@ #line 109 def keyword_only_arg(*, arg): pass + +@wrap(lambda: None) +def func114(): + return 115 + +@wrap() +class DecoratedClass: + pass + +@wrap(lambda: None) +class DecoratedLambdaClass: + pass + +class ClassWithMethod: + def method(self): + pass diff -r bdde36cd9048 Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Mon Apr 14 10:28:58 2014 -0400 +++ b/Lib/test/test_inspect.py Mon Apr 14 18:40:20 2014 -0400 @@ -357,6 +357,9 @@ finally: linecache.getlines = getlines + def test_getsource_on_code_object(self): + self.assertSourceEqual(mod.eggs.__code__, 12, 18) + class TestDecorators(GetSourceBase): fodderModule = mod2 @@ -366,6 +369,15 @@ def test_replacing_decorator(self): self.assertSourceEqual(mod2.gone, 9, 10) + def test_decorator_with_lambda(self): + self.assertSourceEqual(mod2.func114, 113, 115) + + def test_decorated_class(self): + self.assertSourceEqual(mod2.DecoratedClass, 118, 119) + + def test_decorated_class_with_lambda(self): + self.assertSourceEqual(mod2.DecoratedLambdaClass, 122, 123) + class TestOneliners(GetSourceBase): fodderModule = mod2 def test_oneline_lambda(self): @@ -458,6 +470,9 @@ self.assertRaises(IOError, inspect.findsource, co) self.assertRaises(IOError, inspect.getsource, co) + def test_getsource_on_method(self): + self.assertSourceEqual(mod2.ClassWithMethod.method, 126, 127) + class TestNoEOL(GetSourceBase): def __init__(self, *args, **kwargs): self.tempdir = TESTFN + '_dir'