Index: inspect.py =================================================================== --- inspect.py (revision 74440) +++ inspect.py (working copy) @@ -621,6 +621,7 @@ return string.join(comments, '') class EndOfBlock(Exception): pass +class OutermostBlock(Exception): pass class BlockFinder: """Provide a tokeneater() method to detect the end of a code block.""" @@ -629,11 +630,27 @@ self.islambda = False self.started = False self.passline = False + self.firsttoken = True self.last = 1 def tokeneater(self, type, token, srow_scol, erow_ecol, line): srow, scol = srow_scol erow, ecol = erow_ecol + + # Skip over initial comments. If the source lines start with + # "def" or "class" (optionally decorated), continue until + # a matching dedent ends this block. + # If they start with any other token (but not INDENT) then + # this is the outermost block -- *unless* a lambda appears in + # the same line; in such case assume the code corresponds to + # the lambda expression. + if self.firsttoken and type not in (tokenize.COMMENT, + tokenize.NL, tokenize.NEWLINE): + if type != tokenize.INDENT: + if token not in ("@", "def", "class") and "lambda" not in line: + raise OutermostBlock + self.firsttoken = False + if not self.started: # look for the first "def", "class" or "lambda" if token in ("def", "class", "lambda"): @@ -668,6 +685,8 @@ blockfinder = BlockFinder() try: tokenize.tokenize(iter(lines).next, blockfinder.tokeneater) + except OutermostBlock: + return lines except (EndOfBlock, IndentationError): pass return lines[:blockfinder.last] Index: test/test_inspect.py =================================================================== --- test/test_inspect.py (revision 74441) +++ test/test_inspect.py (working copy) @@ -184,6 +184,11 @@ class TestRetrievingSourceCode(GetSourceBase): fodderFile = mod + def __init__(self, *args, **kwargs): + GetSourceBase.__init__(self, *args, **kwargs) + + git.abuse(7, 8, 9) # required for mod.fr attribute to exist + def test_getclasses(self): classes = inspect.getmembers(mod, inspect.isclass) self.assertEqual(classes, @@ -237,8 +242,14 @@ self.assertEqual(inspect.getmodule(None, modfile), mod) def test_getsource(self): - self.assertSourceEqual(git.abuse, 29, 39) - self.assertSourceEqual(mod.StupidGit, 21, 46) + self.assertSourceEqual(mod, 1, 63) # module + self.assertSourceEqual(mod.StupidGit, 21, 46) # class + self.assertSourceEqual(git.abuse, 29, 39) # method + self.assertSourceEqual(mod.eggs, 12, 18) # function + self.assertSourceEqual(mod.tb, 1, 63) # traceback + self.assertSourceEqual(mod.fr, 12, 18) # frame + self.assertSourceEqual(mod.ofr, 1, 63) # frame (outer) + self.assertSourceEqual(mod.spam.func_code, 8, 9) # code def test_getsourcefile(self): self.assertEqual(inspect.getsourcefile(mod.spam), modfile) Index: test/inspect_fodder.py =================================================================== --- test/inspect_fodder.py (revision 74441) +++ test/inspect_fodder.py (working copy) @@ -54,3 +54,10 @@ class FesteringGob(MalodorousPervert, ParrotDroppings): pass + +# line 58 +ofr = inspect.currentframe() +try: + 1/0 +except: + tb = sys.exc_info()[2]