| LEFT | RIGHT |
| 1 #! /usr/bin/env python3 | 1 #! /usr/bin/env python3 |
| 2 | 2 |
| 3 # Released to the public domain, by Tim Peters, 03 October 2000. | 3 # Released to the public domain, by Tim Peters, 03 October 2000. |
| 4 | 4 |
| 5 """reindent [-d][-r][-v] [ path ... ] | 5 """reindent [-d][-r][-v] [ path ... ] |
| 6 | 6 |
| 7 -d (--dryrun) Dry run. Analyze, but don't make any changes to, files. | 7 -d (--dryrun) Dry run. Analyze, but don't make any changes to, files. |
| 8 -r (--recurse) Recurse. Search for all .py files in subdirectories too. | 8 -r (--recurse) Recurse. Search for all .py files in subdirectories too. |
| 9 -n (--nobackup) No backup. Does not make a ".bak" file before reindenting. | 9 -n (--nobackup) No backup. Does not make a ".bak" file before reindenting. |
| 10 -v (--verbose) Verbose. Print informative msgs; else no output. | 10 -v (--verbose) Verbose. Print informative msgs; else no output. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 tabnanny.py, reindent should do a good job. | 34 tabnanny.py, reindent should do a good job. |
| 35 | 35 |
| 36 The backup file is a copy of the one that is being reindented. The ".bak" | 36 The backup file is a copy of the one that is being reindented. The ".bak" |
| 37 file is generated with shutil.copy(), but some corner cases regarding | 37 file is generated with shutil.copy(), but some corner cases regarding |
| 38 user/group and permissions could leave the backup file more readable that | 38 user/group and permissions could leave the backup file more readable that |
| 39 you'd prefer. You can always use the --nobackup option to prevent this. | 39 you'd prefer. You can always use the --nobackup option to prevent this. |
| 40 """ | 40 """ |
| 41 | 41 |
| 42 __version__ = "1" | 42 __version__ = "1" |
| 43 | 43 |
| 44 import tokenize | 44 import io |
| 45 import os | 45 import os |
| 46 import shutil | 46 import shutil |
| 47 import sys | 47 import sys |
| 48 import tokenize |
| 48 | 49 |
| 49 verbose = False | 50 verbose = False |
| 50 recurse = False | 51 recurse = False |
| 51 dryrun = False | 52 dryrun = False |
| 52 makebackup = True | 53 makebackup = True |
| 53 | 54 |
| 54 | 55 |
| 55 def usage(msg=None): | 56 def usage(msg=None): |
| 56 if msg is None: | 57 if msg is None: |
| 57 msg = __doc__ | 58 msg = __doc__ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 78 elif o in ('-r', '--recurse'): | 79 elif o in ('-r', '--recurse'): |
| 79 recurse = True | 80 recurse = True |
| 80 elif o in ('-n', '--nobackup'): | 81 elif o in ('-n', '--nobackup'): |
| 81 makebackup = False | 82 makebackup = False |
| 82 elif o in ('-v', '--verbose'): | 83 elif o in ('-v', '--verbose'): |
| 83 verbose = True | 84 verbose = True |
| 84 elif o in ('-h', '--help'): | 85 elif o in ('-h', '--help'): |
| 85 usage() | 86 usage() |
| 86 return | 87 return |
| 87 if not args: | 88 if not args: |
| 88 r = Reindenter(sys.stdin) | 89 content = sys.stdin.buffer.read() |
| 90 raw = io.BytesIO(content) |
| 91 buffer = io.BufferedReader(raw) |
| 92 encoding, _ = tokenize.detect_encoding(buffer.readline) |
| 93 buffer.seek(0) |
| 94 text = io.TextIOWrapper(buffer, encoding) |
| 95 |
| 96 r = Reindenter(text) |
| 89 r.run() | 97 r.run() |
| 90 r.write(sys.stdout) | 98 r.write(sys.stdout.buffer, encoding) |
| 91 return | 99 return |
| 92 for arg in args: | 100 for arg in args: |
| 93 check(arg) | 101 check(arg) |
| 94 | 102 |
| 95 | 103 |
| 96 def check(file): | 104 def check(file): |
| 97 if os.path.isdir(file) and not os.path.islink(file): | 105 if os.path.isdir(file) and not os.path.islink(file): |
| 98 if verbose: | 106 if verbose: |
| 99 print("listing directory", file) | 107 print("listing directory", file) |
| 100 names = os.listdir(file) | 108 names = os.listdir(file) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 122 if verbose: | 130 if verbose: |
| 123 print("changed.") | 131 print("changed.") |
| 124 if dryrun: | 132 if dryrun: |
| 125 print("But this is a dry run, so leaving it alone.") | 133 print("But this is a dry run, so leaving it alone.") |
| 126 if not dryrun: | 134 if not dryrun: |
| 127 bak = file + ".bak" | 135 bak = file + ".bak" |
| 128 if makebackup: | 136 if makebackup: |
| 129 shutil.copyfile(file, bak) | 137 shutil.copyfile(file, bak) |
| 130 if verbose: | 138 if verbose: |
| 131 print("backed up", file, "to", bak) | 139 print("backed up", file, "to", bak) |
| 132 with open(file, "w", encoding=encoding) as f: | 140 with open(file, "wb") as f: |
| 133 r.write(f) | 141 r.write(f, encoding) |
| 134 if verbose: | 142 if verbose: |
| 135 print("wrote new", file) | 143 print("wrote new", file) |
| 136 return True | 144 return True |
| 137 else: | 145 else: |
| 138 if verbose: | 146 if verbose: |
| 139 print("unchanged.") | 147 print("unchanged.") |
| 140 return False | 148 return False |
| 141 | 149 |
| 142 | 150 |
| 143 def _rstrip(line, JUNK='\n \t'): | 151 def _rstrip(line, JUNK='\n \t'): |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 if diff > 0: | 249 if diff > 0: |
| 242 if line == "\n": | 250 if line == "\n": |
| 243 after.append(line) | 251 after.append(line) |
| 244 else: | 252 else: |
| 245 after.append(" " * diff + line) | 253 after.append(" " * diff + line) |
| 246 else: | 254 else: |
| 247 remove = min(getlspace(line), -diff) | 255 remove = min(getlspace(line), -diff) |
| 248 after.append(line[remove:]) | 256 after.append(line[remove:]) |
| 249 return self.raw != self.after | 257 return self.raw != self.after |
| 250 | 258 |
| 251 def write(self, f): | 259 def write(self, f, encoding): |
| 252 f.writelines(self.after) | 260 for line in self.after: |
| 261 line = line.encode(encoding) |
| 262 f.write(line) |
| 253 | 263 |
| 254 # Line-getter for tokenize. | 264 # Line-getter for tokenize. |
| 255 def getline(self): | 265 def getline(self): |
| 256 if self.index >= len(self.lines): | 266 if self.index >= len(self.lines): |
| 257 line = "" | 267 line = "" |
| 258 else: | 268 else: |
| 259 line = self.lines[self.index] | 269 line = self.lines[self.index] |
| 260 self.index += 1 | 270 self.index += 1 |
| 261 return line | 271 return line |
| 262 | 272 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 # Count number of leading blanks. | 313 # Count number of leading blanks. |
| 304 def getlspace(line): | 314 def getlspace(line): |
| 305 i, n = 0, len(line) | 315 i, n = 0, len(line) |
| 306 while i < n and line[i] == " ": | 316 while i < n and line[i] == " ": |
| 307 i += 1 | 317 i += 1 |
| 308 return i | 318 return i |
| 309 | 319 |
| 310 | 320 |
| 311 if __name__ == '__main__': | 321 if __name__ == '__main__': |
| 312 main() | 322 main() |
| LEFT | RIGHT |