some more fixes and tests for inspect.getsource(), triggered by crashes
from the PyPy project as well as the SF bug #1295909.
diff --git a/Lib/inspect.py b/Lib/inspect.py
index a801a29..57bf18c 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -485,19 +485,6 @@
                 comments[-1:] = []
             return string.join(comments, '')
 
-class ListReader:
-    """Provide a readline() method to return lines from a list of strings."""
-    def __init__(self, lines):
-        self.lines = lines
-        self.index = 0
-
-    def readline(self):
-        i = self.index
-        if i < len(self.lines):
-            self.index = i + 1
-            return self.lines[i]
-        else: return ''
-
 class EndOfBlock(Exception): pass
 
 class BlockFinder:
@@ -507,40 +494,46 @@
         self.islambda = False
         self.started = False
         self.passline = False
-        self.last = 0
+        self.last = 1
 
     def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
         if not self.started:
+            # look for the first "def", "class" or "lambda"
             if token in ("def", "class", "lambda"):
                 if token == "lambda":
                     self.islambda = True
                 self.started = True
-            self.passline = True
+            self.passline = True    # skip to the end of the line
         elif type == tokenize.NEWLINE:
-            self.passline = False
+            self.passline = False   # stop skipping when a NEWLINE is seen
             self.last = srow
+            if self.islambda:       # lambdas always end at the first NEWLINE
+                raise EndOfBlock
         elif self.passline:
             pass
-        elif self.islambda:
-            raise EndOfBlock, self.last
         elif type == tokenize.INDENT:
             self.indent = self.indent + 1
             self.passline = True
         elif type == tokenize.DEDENT:
             self.indent = self.indent - 1
-            if self.indent == 0:
-                raise EndOfBlock, self.last
-        elif type == tokenize.NAME and scol == 0:
-            raise EndOfBlock, self.last
+            # the end of matching indent/dedent pairs end a block
+            # (note that this only works for "def"/"class" blocks,
+            #  not e.g. for "if: else:" or "try: finally:" blocks)
+            if self.indent <= 0:
+                raise EndOfBlock
+        elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
+            # any other token on the same indentation level end the previous
+            # block as well, except the pseudo-tokens COMMENT and NL.
+            raise EndOfBlock
 
 def getblock(lines):
     """Extract the block of code at the top of the given list of lines."""
+    blockfinder = BlockFinder()
     try:
-        tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater)
-    except EndOfBlock, eob:
-        return lines[:eob.args[0]]
-    # Fooling the indent/dedent logic implies a one-line definition
-    return lines[:1]
+        tokenize.tokenize(iter(lines).next, blockfinder.tokeneater)
+    except (EndOfBlock, IndentationError):
+        pass
+    return lines[:blockfinder.last]
 
 def getsourcelines(object):
     """Return a list of source lines and starting line number for an object.
diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py
index f216c82..f150ec6 100644
--- a/Lib/test/inspect_fodder2.py
+++ b/Lib/test/inspect_fodder2.py
@@ -64,3 +64,27 @@
             y): x+y,
     None,
     ]
+
+# line 68
+def func69():
+    class cls70:
+        def func71():
+            pass
+    return cls70
+extra74 = 74
+
+# line 76
+def func77(): pass
+(extra78, stuff78) = 'xy'
+extra79 = 'stop'
+
+# line 81
+class cls82:
+    def func83(): pass
+(extra84, stuff84) = 'xy'
+extra85 = 'stop'
+
+# line 87
+def func88():
+    # comment
+    return 90
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index 1fb48c5..ce346b9 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -238,6 +238,18 @@
     def test_multiline_sig(self):
         self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
 
+    def test_nested_class(self):
+        self.assertSourceEqual(mod2.func69().func71, 71, 72)
+
+    def test_one_liner_followed_by_non_name(self):
+        self.assertSourceEqual(mod2.func77, 77, 77)
+
+    def test_one_liner_dedent_non_name(self):
+        self.assertSourceEqual(mod2.cls82.func83, 83, 83)
+
+    def test_with_comment_instead_of_docstring(self):
+        self.assertSourceEqual(mod2.func88, 88, 90)
+
 # Helper for testing classify_class_attrs.
 def attrs_wo_objs(cls):
     return [t[:3] for t in inspect.classify_class_attrs(cls)]