edit: rewrote to accomodate fileinput
's "eccentricities"*
def indent_code(filename, startline, endline):
from fileinput import input
from itertools import izip, count
all_remaining = count()
def print_lines(lines, prefix='', range=all_remaining):
for _, line in izip(range, lines):
print prefix + line,
lines = input(filename, inplace=1)
print_lines(lines, range=xrange(1, startline)) # 1-based line numbers
print_lines(lines, ' ', xrange(startline, endline + 1)) # inclusive
print_lines(lines)
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('filename')
parser.add_argument('startline', type=int)
parser.add_argument('endline', type=int)
ns = parser.parse_args()
indent_code(ns.filename, ns.startline, ns.endline)
if __name__ == '__main__':
main()
Well, either that or >}
.
*: I originally wrote this using a nice, concise combination of stdout.writelines
and some generator expressions. Unfortunately, that code didn't work. The iterator returned by fileinput.input()
doesn't actually open a file until you call its next
method. It works its sketchy output-redirection magic on sys.stdout
at the same time. This means that if you call sys.stdout.writelines
and pass it the fileinput.input
iterator, your call, and the output, goes to the original standard out rather than the one remapped by fileinput
to the file "currently" being processed. So you end up with the lines that are supposed to replace the contents of the file being instead just printed to the terminal.
It's possible to work around this issue by calling next
on the fileinput iterator before calling stdout.writelines
, but this causes other problems: reaching the end of the input file causes its handle to be closed from the iterator's next
method when called within file.writelines
. Under Python 2.6, this segfaults because there's no check made (in the C code which implements writelines
) to see if the file is still open, and the file handle non-zero, after getting the next value from the iterator. I think under 2.7 it just throws an exception, so this strategy might work there.
The above code actually does test correctly.