bpo-22831: Use "with" to avoid possible fd leaks in tools (part 1). (GH-10926)

This commit is contained in:
Serhiy Storchaka 2019-03-30 08:32:18 +02:00 committed by GitHub
parent 2524fdefc9
commit afbb7a371f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 226 additions and 228 deletions

View File

@ -281,36 +281,36 @@ def addsubst(substfile):
except IOError as msg: except IOError as msg:
err(substfile + ': cannot read substfile: ' + str(msg) + '\n') err(substfile + ': cannot read substfile: ' + str(msg) + '\n')
sys.exit(1) sys.exit(1)
lineno = 0 with fp:
while 1: lineno = 0
line = fp.readline() while 1:
if not line: break line = fp.readline()
lineno = lineno + 1 if not line: break
try: lineno = lineno + 1
i = line.index('#') try:
except ValueError: i = line.index('#')
i = -1 # Happens to delete trailing \n except ValueError:
words = line[:i].split() i = -1 # Happens to delete trailing \n
if not words: continue words = line[:i].split()
if len(words) == 3 and words[0] == 'struct': if not words: continue
words[:2] = [words[0] + ' ' + words[1]] if len(words) == 3 and words[0] == 'struct':
elif len(words) != 2: words[:2] = [words[0] + ' ' + words[1]]
err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line)) elif len(words) != 2:
continue err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line))
if Reverse: continue
[value, key] = words if Reverse:
else: [value, key] = words
[key, value] = words else:
if value[0] == '*': [key, value] = words
value = value[1:] if value[0] == '*':
if key[0] == '*': value = value[1:]
key = key[1:] if key[0] == '*':
NotInComment[key] = value key = key[1:]
if key in Dict: NotInComment[key] = value
err('%s:%r: warning: overriding: %r %r\n' % (substfile, lineno, key, value)) if key in Dict:
err('%s:%r: warning: previous: %r\n' % (substfile, lineno, Dict[key])) err('%s:%r: warning: overriding: %r %r\n' % (substfile, lineno, key, value))
Dict[key] = value err('%s:%r: warning: previous: %r\n' % (substfile, lineno, Dict[key]))
fp.close() Dict[key] = value
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -179,27 +179,27 @@ PATTERN = (r"^(.+?):(\d+): DeprecationWarning: "
def readwarnings(warningsfile): def readwarnings(warningsfile):
prog = re.compile(PATTERN) prog = re.compile(PATTERN)
warnings = {}
try: try:
f = open(warningsfile) f = open(warningsfile)
except IOError as msg: except IOError as msg:
sys.stderr.write("can't open: %s\n" % msg) sys.stderr.write("can't open: %s\n" % msg)
return return
warnings = {} with f:
while 1: while 1:
line = f.readline() line = f.readline()
if not line: if not line:
break break
m = prog.match(line) m = prog.match(line)
if not m: if not m:
if line.find("division") >= 0: if line.find("division") >= 0:
sys.stderr.write("Warning: ignored input " + line) sys.stderr.write("Warning: ignored input " + line)
continue continue
filename, lineno, what = m.groups() filename, lineno, what = m.groups()
list = warnings.get(filename) list = warnings.get(filename)
if list is None: if list is None:
warnings[filename] = list = [] warnings[filename] = list = []
list.append((int(lineno), sys.intern(what))) list.append((int(lineno), sys.intern(what)))
f.close()
return warnings return warnings
def process(filename, list): def process(filename, list):
@ -210,84 +210,84 @@ def process(filename, list):
except IOError as msg: except IOError as msg:
sys.stderr.write("can't open: %s\n" % msg) sys.stderr.write("can't open: %s\n" % msg)
return 1 return 1
print("Index:", filename) with fp:
f = FileContext(fp) print("Index:", filename)
list.sort() f = FileContext(fp)
index = 0 # list[:index] has been processed, list[index:] is still to do list.sort()
g = tokenize.generate_tokens(f.readline) index = 0 # list[:index] has been processed, list[index:] is still to do
while 1: g = tokenize.generate_tokens(f.readline)
startlineno, endlineno, slashes = lineinfo = scanline(g) while 1:
if startlineno is None: startlineno, endlineno, slashes = lineinfo = scanline(g)
break if startlineno is None:
assert startlineno <= endlineno is not None break
orphans = [] assert startlineno <= endlineno is not None
while index < len(list) and list[index][0] < startlineno: orphans = []
orphans.append(list[index]) while index < len(list) and list[index][0] < startlineno:
index += 1 orphans.append(list[index])
if orphans: index += 1
reportphantomwarnings(orphans, f) if orphans:
warnings = [] reportphantomwarnings(orphans, f)
while index < len(list) and list[index][0] <= endlineno: warnings = []
warnings.append(list[index]) while index < len(list) and list[index][0] <= endlineno:
index += 1 warnings.append(list[index])
if not slashes and not warnings: index += 1
pass if not slashes and not warnings:
elif slashes and not warnings: pass
report(slashes, "No conclusive evidence") elif slashes and not warnings:
elif warnings and not slashes: report(slashes, "No conclusive evidence")
reportphantomwarnings(warnings, f) elif warnings and not slashes:
else: reportphantomwarnings(warnings, f)
if len(slashes) > 1: else:
if not multi_ok: if len(slashes) > 1:
rows = [] if not multi_ok:
lastrow = None rows = []
for (row, col), line in slashes: lastrow = None
if row == lastrow: for (row, col), line in slashes:
continue if row == lastrow:
rows.append(row) continue
lastrow = row rows.append(row)
assert rows lastrow = row
if len(rows) == 1: assert rows
print("*** More than one / operator in line", rows[0]) if len(rows) == 1:
print("*** More than one / operator in line", rows[0])
else:
print("*** More than one / operator per statement", end=' ')
print("in lines %d-%d" % (rows[0], rows[-1]))
intlong = []
floatcomplex = []
bad = []
for lineno, what in warnings:
if what in ("int", "long"):
intlong.append(what)
elif what in ("float", "complex"):
floatcomplex.append(what)
else: else:
print("*** More than one / operator per statement", end=' ') bad.append(what)
print("in lines %d-%d" % (rows[0], rows[-1])) lastrow = None
intlong = [] for (row, col), line in slashes:
floatcomplex = [] if row == lastrow:
bad = [] continue
for lineno, what in warnings: lastrow = row
if what in ("int", "long"): line = chop(line)
intlong.append(what) if line[col:col+1] != "/":
elif what in ("float", "complex"): print("*** Can't find the / operator in line %d:" % row)
floatcomplex.append(what) print("*", line)
else: continue
bad.append(what) if bad:
lastrow = None print("*** Bad warning for line %d:" % row, bad)
for (row, col), line in slashes: print("*", line)
if row == lastrow: elif intlong and not floatcomplex:
continue print("%dc%d" % (row, row))
lastrow = row print("<", line)
line = chop(line) print("---")
if line[col:col+1] != "/": print(">", line[:col] + "/" + line[col:])
print("*** Can't find the / operator in line %d:" % row) elif floatcomplex and not intlong:
print("*", line) print("True division / operator at line %d:" % row)
continue print("=", line)
if bad: elif intlong and floatcomplex:
print("*** Bad warning for line %d:" % row, bad) print("*** Ambiguous / operator (%s, %s) at line %d:" %
print("*", line) ("|".join(intlong), "|".join(floatcomplex), row))
elif intlong and not floatcomplex: print("?", line)
print("%dc%d" % (row, row))
print("<", line)
print("---")
print(">", line[:col] + "/" + line[col:])
elif floatcomplex and not intlong:
print("True division / operator at line %d:" % row)
print("=", line)
elif intlong and floatcomplex:
print("*** Ambiguous / operator (%s, %s) at line %d:" % (
"|".join(intlong), "|".join(floatcomplex), row))
print("?", line)
fp.close()
def reportphantomwarnings(warnings, f): def reportphantomwarnings(warnings, f):
blocks = [] blocks = []

View File

@ -15,8 +15,8 @@ def process(filename):
except IOError as msg: except IOError as msg:
sys.stderr.write('%s: can\'t open: %s\n' % (filename, str(msg))) sys.stderr.write('%s: can\'t open: %s\n' % (filename, str(msg)))
return return
data = f.read() with f:
f.close() data = f.read()
if data[:2] != '/*': if data[:2] != '/*':
sys.stderr.write('%s does not begin with C comment\n' % filename) sys.stderr.write('%s does not begin with C comment\n' % filename)
return return
@ -25,25 +25,25 @@ def process(filename):
except IOError as msg: except IOError as msg:
sys.stderr.write('%s: can\'t write: %s\n' % (filename, str(msg))) sys.stderr.write('%s: can\'t write: %s\n' % (filename, str(msg)))
return return
sys.stderr.write('Processing %s ...\n' % filename) with f:
magic = 'Py_' sys.stderr.write('Processing %s ...\n' % filename)
for c in filename: magic = 'Py_'
if ord(c)<=0x80 and c.isalnum(): for c in filename:
magic = magic + c.upper() if ord(c)<=0x80 and c.isalnum():
else: magic = magic + '_' magic = magic + c.upper()
sys.stdout = f else: magic = magic + '_'
print('#ifndef', magic) print('#ifndef', magic, file=f)
print('#define', magic) print('#define', magic, file=f)
print('#ifdef __cplusplus') print('#ifdef __cplusplus', file=f)
print('extern "C" {') print('extern "C" {', file=f)
print('#endif') print('#endif', file=f)
print() print(file=f)
f.write(data) f.write(data)
print() print(file=f)
print('#ifdef __cplusplus') print('#ifdef __cplusplus', file=f)
print('}') print('}', file=f)
print('#endif') print('#endif', file=f)
print('#endif /*', '!'+magic, '*/') print('#endif /*', '!'+magic, '*/', file=f)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -28,14 +28,7 @@ def add_escapes(filename):
for line in fp: for line in fp:
yield html.escape(line) yield html.escape(line)
def gprof2html(input, output, filename):
def main():
filename = "gprof.out"
if sys.argv[1:]:
filename = sys.argv[1]
outputfilename = filename + ".html"
input = add_escapes(filename)
output = open(outputfilename, "w")
output.write(header % filename) output.write(header % filename)
for line in input: for line in input:
output.write(line) output.write(line)
@ -78,7 +71,16 @@ def main():
part = '<a href="#call:%s">%s</a>' % (part, part) part = '<a href="#call:%s">%s</a>' % (part, part)
output.write(part) output.write(part)
output.write(trailer) output.write(trailer)
output.close()
def main():
filename = "gprof.out"
if sys.argv[1:]:
filename = sys.argv[1]
outputfilename = filename + ".html"
input = add_escapes(filename)
with open(outputfilename, "w") as output:
gprof2html(input, output, filename)
webbrowser.open("file:" + os.path.abspath(outputfilename)) webbrowser.open("file:" + os.path.abspath(outputfilename))
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -118,11 +118,10 @@ class HTMLNode:
self.lines.append(line) self.lines.append(line)
def flush(self): def flush(self):
fp = open(self.dirname + '/' + makefile(self.name), 'w') with open(self.dirname + '/' + makefile(self.name), 'w') as fp:
fp.write(self.prologue) fp.write(self.prologue)
fp.write(self.text) fp.write(self.text)
fp.write(self.epilogue) fp.write(self.epilogue)
fp.close()
def link(self, label, nodename, rel=None, rev=None): def link(self, label, nodename, rel=None, rev=None):
if nodename: if nodename:
@ -558,14 +557,14 @@ class TexinfoParser:
except IOError as msg: except IOError as msg:
print('*** Can\'t open include file', repr(file)) print('*** Can\'t open include file', repr(file))
return return
print('!'*self.debugging, '--> file', repr(file)) with fp:
save_done = self.done print('!'*self.debugging, '--> file', repr(file))
save_skip = self.skip save_done = self.done
save_stack = self.stack save_skip = self.skip
self.includedepth = self.includedepth + 1 save_stack = self.stack
self.parserest(fp, 0) self.includedepth = self.includedepth + 1
self.includedepth = self.includedepth - 1 self.parserest(fp, 0)
fp.close() self.includedepth = self.includedepth - 1
self.done = save_done self.done = save_done
self.skip = save_skip self.skip = save_skip
self.stack = save_stack self.stack = save_stack
@ -1770,78 +1769,75 @@ class HTMLHelp:
# PROJECT FILE # PROJECT FILE
try: try:
fp = open(projectfile,'w') with open(projectfile, 'w') as fp:
print('[OPTIONS]', file=fp) print('[OPTIONS]', file=fp)
print('Auto Index=Yes', file=fp) print('Auto Index=Yes', file=fp)
print('Binary TOC=No', file=fp) print('Binary TOC=No', file=fp)
print('Binary Index=Yes', file=fp) print('Binary Index=Yes', file=fp)
print('Compatibility=1.1', file=fp) print('Compatibility=1.1', file=fp)
print('Compiled file=' + resultfile + '', file=fp) print('Compiled file=' + resultfile + '', file=fp)
print('Contents file=' + contentfile + '', file=fp) print('Contents file=' + contentfile + '', file=fp)
print('Default topic=' + defaulttopic + '', file=fp) print('Default topic=' + defaulttopic + '', file=fp)
print('Error log file=ErrorLog.log', file=fp) print('Error log file=ErrorLog.log', file=fp)
print('Index file=' + indexfile + '', file=fp) print('Index file=' + indexfile + '', file=fp)
print('Title=' + title + '', file=fp) print('Title=' + title + '', file=fp)
print('Display compile progress=Yes', file=fp) print('Display compile progress=Yes', file=fp)
print('Full-text search=Yes', file=fp) print('Full-text search=Yes', file=fp)
print('Default window=main', file=fp) print('Default window=main', file=fp)
print('', file=fp) print('', file=fp)
print('[WINDOWS]', file=fp) print('[WINDOWS]', file=fp)
print('main=,"' + contentfile + '","' + indexfile print('main=,"' + contentfile + '","' + indexfile
+ '","","",,,,,0x23520,222,0x1046,[10,10,780,560],' + '","","",,,,,0x23520,222,0x1046,[10,10,780,560],'
'0xB0000,,,,,,0', file=fp) '0xB0000,,,,,,0', file=fp)
print('', file=fp) print('', file=fp)
print('[FILES]', file=fp) print('[FILES]', file=fp)
print('', file=fp) print('', file=fp)
self.dumpfiles(fp) self.dumpfiles(fp)
fp.close()
except IOError as msg: except IOError as msg:
print(projectfile, ':', msg) print(projectfile, ':', msg)
sys.exit(1) sys.exit(1)
# CONTENT FILE # CONTENT FILE
try: try:
fp = open(contentfile,'w') with open(contentfile, 'w') as fp:
print('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">', file=fp) print('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">', file=fp)
print('<!-- This file defines the table of contents -->', file=fp) print('<!-- This file defines the table of contents -->', file=fp)
print('<HTML>', file=fp) print('<HTML>', file=fp)
print('<HEAD>', file=fp) print('<HEAD>', file=fp)
print('<meta name="GENERATOR" ' print('<meta name="GENERATOR" '
'content="Microsoft&reg; HTML Help Workshop 4.1">', file=fp) 'content="Microsoft&reg; HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp) print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp) print('</HEAD>', file=fp)
print('<BODY>', file=fp) print('<BODY>', file=fp)
print(' <OBJECT type="text/site properties">', file=fp) print(' <OBJECT type="text/site properties">', file=fp)
print(' <param name="Window Styles" value="0x800025">', file=fp) print(' <param name="Window Styles" value="0x800025">', file=fp)
print(' <param name="comment" value="title:">', file=fp) print(' <param name="comment" value="title:">', file=fp)
print(' <param name="comment" value="base:">', file=fp) print(' <param name="comment" value="base:">', file=fp)
print(' </OBJECT>', file=fp) print(' </OBJECT>', file=fp)
self.dumpnodes(fp) self.dumpnodes(fp)
print('</BODY>', file=fp) print('</BODY>', file=fp)
print('</HTML>', file=fp) print('</HTML>', file=fp)
fp.close()
except IOError as msg: except IOError as msg:
print(contentfile, ':', msg) print(contentfile, ':', msg)
sys.exit(1) sys.exit(1)
# INDEX FILE # INDEX FILE
try: try:
fp = open(indexfile ,'w') with open(indexfile, 'w') as fp:
print('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">', file=fp) print('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">', file=fp)
print('<!-- This file defines the index -->', file=fp) print('<!-- This file defines the index -->', file=fp)
print('<HTML>', file=fp) print('<HTML>', file=fp)
print('<HEAD>', file=fp) print('<HEAD>', file=fp)
print('<meta name="GENERATOR" ' print('<meta name="GENERATOR" '
'content="Microsoft&reg; HTML Help Workshop 4.1">', file=fp) 'content="Microsoft&reg; HTML Help Workshop 4.1">', file=fp)
print('<!-- Sitemap 1.0 -->', file=fp) print('<!-- Sitemap 1.0 -->', file=fp)
print('</HEAD>', file=fp) print('</HEAD>', file=fp)
print('<BODY>', file=fp) print('<BODY>', file=fp)
print('<OBJECT type="text/site properties">', file=fp) print('<OBJECT type="text/site properties">', file=fp)
print('</OBJECT>', file=fp) print('</OBJECT>', file=fp)
self.dumpindex(fp) self.dumpindex(fp)
print('</BODY>', file=fp) print('</BODY>', file=fp)
print('</HTML>', file=fp) print('</HTML>', file=fp)
fp.close()
except IOError as msg: except IOError as msg:
print(indexfile , ':', msg) print(indexfile , ':', msg)
sys.exit(1) sys.exit(1)
@ -2064,8 +2060,8 @@ def test():
print(file, ':', msg) print(file, ':', msg)
sys.exit(1) sys.exit(1)
parser.parse(fp) with fp:
fp.close() parser.parse(fp)
parser.report() parser.report()
htmlhelp.finalize() htmlhelp.finalize()