Mercurial > cpython-lru_cache-weakref
annotate Tools/scripts/methfix.py @ 6719:faebc1940432 legacy-trunk
Understand -Xlinker option.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Tue, 02 Dec 1997 20:38:11 +0000 |
| parents | 73758db2f464 |
| children | 14a27acc755a |
| rev | line source |
|---|---|
|
4573
73758db2f464
/usr/local/bin/python -> /usr/bin/env python
Guido van Rossum <guido@python.org>
parents:
1506
diff
changeset
|
1 #! /usr/bin/env python |
| 1104 | 2 |
| 3 # Fix Python source files to avoid using | |
| 4 # def method(self, (arg1, ..., argn)): | |
| 5 # instead of the more rational | |
| 6 # def method(self, arg1, ..., argn): | |
| 7 # | |
| 8 # Command line arguments are files or directories to be processed. | |
| 9 # Directories are searched recursively for files whose name looks | |
| 10 # like a python module. | |
| 11 # Symbolic links are always ignored (except as explicit directory | |
| 12 # arguments). Of course, the original file is kept as a back-up | |
| 13 # (with a "~" attached to its name). | |
| 14 # It complains about binaries (files containing null bytes) | |
| 15 # and about files that are ostensibly not Python files: if the first | |
| 16 # line starts with '#!' and does not contain the string 'python'. | |
| 17 # | |
| 18 # Changes made are reported to stdout in a diff-like format. | |
| 19 # | |
| 20 # Undoubtedly you can do this using find and sed or perl, but this is | |
| 21 # a nice example of Python code that recurses down a directory tree | |
| 22 # and uses regular expressions. Also note several subtleties like | |
| 23 # preserving the file's mode and avoiding to even write a temp file | |
| 24 # when no changes are needed for a file. | |
| 25 # | |
| 26 # NB: by changing only the function fixline() you can turn this | |
| 27 # into a program for a different change to Python programs... | |
| 28 | |
| 29 import sys | |
| 30 import regex | |
| 31 import os | |
| 32 from stat import * | |
| 33 import string | |
| 34 | |
| 35 err = sys.stderr.write | |
| 36 dbg = err | |
| 37 rep = sys.stdout.write | |
| 38 | |
| 39 def main(): | |
| 40 bad = 0 | |
| 41 if not sys.argv[1:]: # No arguments | |
| 1266 | 42 err('usage: ' + sys.argv[0] + ' file-or-directory ...\n') |
| 1104 | 43 sys.exit(2) |
| 44 for arg in sys.argv[1:]: | |
| 45 if os.path.isdir(arg): | |
| 46 if recursedown(arg): bad = 1 | |
| 47 elif os.path.islink(arg): | |
| 48 err(arg + ': will not process symbolic links\n') | |
| 49 bad = 1 | |
| 50 else: | |
| 51 if fix(arg): bad = 1 | |
| 52 sys.exit(bad) | |
| 53 | |
| 54 ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$') | |
| 55 def ispython(name): | |
| 56 return ispythonprog.match(name) >= 0 | |
| 57 | |
| 58 def recursedown(dirname): | |
| 59 dbg('recursedown(' + `dirname` + ')\n') | |
| 60 bad = 0 | |
| 61 try: | |
| 62 names = os.listdir(dirname) | |
| 63 except os.error, msg: | |
| 64 err(dirname + ': cannot list directory: ' + `msg` + '\n') | |
| 65 return 1 | |
| 66 names.sort() | |
| 67 subdirs = [] | |
| 68 for name in names: | |
| 69 if name in (os.curdir, os.pardir): continue | |
| 70 fullname = os.path.join(dirname, name) | |
| 71 if os.path.islink(fullname): pass | |
| 72 elif os.path.isdir(fullname): | |
| 73 subdirs.append(fullname) | |
| 74 elif ispython(name): | |
| 75 if fix(fullname): bad = 1 | |
| 76 for fullname in subdirs: | |
| 77 if recursedown(fullname): bad = 1 | |
| 78 return bad | |
| 79 | |
| 80 def fix(filename): | |
| 81 ## dbg('fix(' + `filename` + ')\n') | |
| 82 try: | |
| 83 f = open(filename, 'r') | |
| 84 except IOError, msg: | |
| 85 err(filename + ': cannot open: ' + `msg` + '\n') | |
| 86 return 1 | |
| 87 head, tail = os.path.split(filename) | |
| 88 tempname = os.path.join(head, '@' + tail) | |
| 89 g = None | |
| 90 # If we find a match, we rewind the file and start over but | |
| 91 # now copy everything to a temp file. | |
| 92 lineno = 0 | |
| 93 while 1: | |
| 94 line = f.readline() | |
| 95 if not line: break | |
| 96 lineno = lineno + 1 | |
| 97 if g is None and '\0' in line: | |
| 98 # Check for binary files | |
| 99 err(filename + ': contains null bytes; not fixed\n') | |
| 100 f.close() | |
| 101 return 1 | |
| 102 if lineno == 1 and g is None and line[:2] == '#!': | |
| 103 # Check for non-Python scripts | |
| 104 words = string.split(line[2:]) | |
| 105 if words and regex.search('[pP]ython', words[0]) < 0: | |
| 106 msg = filename + ': ' + words[0] | |
| 107 msg = msg + ' script; not fixed\n' | |
| 108 err(msg) | |
| 109 f.close() | |
| 110 return 1 | |
| 111 while line[-2:] == '\\\n': | |
| 112 nextline = f.readline() | |
| 113 if not nextline: break | |
| 114 line = line + nextline | |
| 115 lineno = lineno + 1 | |
| 116 newline = fixline(line) | |
| 117 if newline != line: | |
| 118 if g is None: | |
| 119 try: | |
| 120 g = open(tempname, 'w') | |
| 121 except IOError, msg: | |
| 122 f.close() | |
| 123 err(tempname+': cannot create: '+\ | |
| 124 `msg`+'\n') | |
| 125 return 1 | |
| 126 f.seek(0) | |
| 127 lineno = 0 | |
| 128 rep(filename + ':\n') | |
| 129 continue # restart from the beginning | |
| 130 rep(`lineno` + '\n') | |
| 131 rep('< ' + line) | |
| 132 rep('> ' + newline) | |
| 133 if g is not None: | |
| 134 g.write(newline) | |
| 135 | |
| 136 # End of file | |
| 137 f.close() | |
| 138 if not g: return 0 # No changes | |
| 139 | |
| 140 # Finishing touch -- move files | |
| 141 | |
| 142 # First copy the file's mode to the temp file | |
| 143 try: | |
| 144 statbuf = os.stat(filename) | |
| 145 os.chmod(tempname, statbuf[ST_MODE] & 07777) | |
| 146 except os.error, msg: | |
| 147 err(tempname + ': warning: chmod failed (' + `msg` + ')\n') | |
| 148 # Then make a backup of the original file as filename~ | |
| 149 try: | |
| 150 os.rename(filename, filename + '~') | |
| 151 except os.error, msg: | |
| 152 err(filename + ': warning: backup failed (' + `msg` + ')\n') | |
| 153 # Now move the temp file to the original file | |
| 154 try: | |
| 155 os.rename(tempname, filename) | |
| 156 except os.error, msg: | |
| 157 err(filename + ': rename failed (' + `msg` + ')\n') | |
| 158 return 1 | |
| 159 # Return succes | |
| 160 return 0 | |
| 161 | |
| 162 | |
| 163 fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *\(( *\(.*\) *)\) *) *:' | |
| 164 fixprog = regex.compile(fixpat) | |
| 165 | |
| 166 def fixline(line): | |
| 167 if fixprog.match(line) >= 0: | |
| 168 (a, b), (c, d) = fixprog.regs[1:3] | |
| 169 line = line[:a] + line[c:d] + line[b:] | |
| 170 return line | |
| 171 | |
| 172 | |
| 173 main() |
