1
from inspect import EndOfBlock
5
"""Provide a tokeneater() method to detect the end of a code block."""
13
def tokeneater(self, type, token, srow_scol, erow_ecol, line):
14
srow, scol = srow_scol
15
erow, ecol = erow_ecol
17
# look for the first "def", "class" or "lambda"
18
if token in ("def", "class", "lambda"):
22
self.passline = True # skip to the end of the line
23
elif type == tokenize.NEWLINE:
24
self.passline = False # stop skipping when a NEWLINE is seen
26
if self.islambda: # lambdas always end at the first NEWLINE
30
elif type == tokenize.INDENT:
31
self.indent = self.indent + 1
33
elif type == tokenize.DEDENT:
34
self.indent = self.indent - 1
35
# the end of matching indent/dedent pairs end a block
36
# (note that this only works for "def"/"class" blocks,
37
# not e.g. for "if: else:" or "try: finally:" blocks)
40
elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
41
# any other token on the same indentation level end the previous
42
# block as well, except the pseudo-tokens COMMENT and NL.
45
blockfinder = BlockFinder()
47
def get_next_block(lines):
51
lines,last = get_block(block)
57
"""Extract the block of code at the top of the given list of lines."""
59
tokenize.tokenize(iter(lines).next, blockfinder.tokeneater)
60
except (EndOfBlock, IndentationError):
62
return lines[:blockfinder.last], blockfinder.last
65
"""Extract the block of code at the top of the given list of lines."""
67
tokenize.tokenize(iter(lines).next, blockfinder.tokeneater)
68
except (EndOfBlock, IndentationError):
70
return lines[:blockfinder.last]
72
lines = file("get_code.py").readlines()
74
for n,(lineno,block) in enumerate(get_next_block(lines)):
76
print "block",lineno,block[-1]