explicitly close files
Add missing calls to close() to many places where files are
opened. Relying on reference counting to catch them soon-ish is not
portable and fails in environments with a proper GC, such as PyPy.
--- a/contrib/check-code.py Fri Feb 11 22:24:10 2011 +0800
+++ b/contrib/check-code.py Fri Dec 24 15:23:01 2010 +0100
@@ -248,7 +248,9 @@
fc = 0
if not re.match(match, f):
continue
- pre = post = open(f).read()
+ fp = open(f)
+ pre = post = fp.read()
+ fp.close()
if "no-" + "check-code" in pre:
break
for p, r in filters:
--- a/hgext/gpg.py Fri Feb 11 22:24:10 2011 +0800
+++ b/hgext/gpg.py Fri Dec 24 15:23:01 2010 +0100
@@ -244,7 +244,9 @@
"(please commit .hgsigs manually "
"or use --force)"))
- repo.wfile(".hgsigs", "ab").write(sigmessage)
+ sigsfile = repo.wfile(".hgsigs", "ab")
+ sigsfile.write(sigmessage)
+ sigsfile.close()
if '.hgsigs' not in repo.dirstate:
repo[None].add([".hgsigs"])
--- a/hgext/inotify/linux/__init__.py Fri Feb 11 22:24:10 2011 +0800
+++ b/hgext/inotify/linux/__init__.py Fri Dec 24 15:23:01 2010 +0100
@@ -26,7 +26,10 @@
def _read_procfs_value(name):
def read_value():
try:
- return int(open(procfs_path + '/' + name).read())
+ fp = open(procfs_path + '/' + name)
+ r = int(fp.read())
+ fp.close()
+ return r
except OSError:
return None
--- a/hgext/mq.py Fri Feb 11 22:24:10 2011 +0800
+++ b/hgext/mq.py Fri Dec 24 15:23:01 2010 +0100
@@ -251,6 +251,7 @@
try:
fh = open(os.path.join(path, 'patches.queue'))
cur = fh.read().rstrip()
+ fh.close()
if not cur:
curpath = os.path.join(path, 'patches')
else:
@@ -1781,7 +1782,9 @@
_('need --name to import a patch from -'))
text = sys.stdin.read()
else:
- text = url.open(self.ui, filename).read()
+ fp = url.open(self.ui, filename)
+ text = fp.read()
+ fp.close()
except (OSError, IOError):
raise util.Abort(_("unable to read file %s") % filename)
if not patchname:
@@ -1790,6 +1793,7 @@
checkfile(patchname)
patchf = self.opener(patchname, "w")
patchf.write(text)
+ patchf.close()
if not force:
checkseries(patchname)
if patchname not in self.series:
@@ -2787,6 +2791,7 @@
try:
fh = repo.opener(_allqueues, 'r')
queues = [queue.strip() for queue in fh if queue.strip()]
+ fh.close()
if current not in queues:
queues.append(current)
except IOError:
--- a/hgext/patchbomb.py Fri Feb 11 22:24:10 2011 +0800
+++ b/hgext/patchbomb.py Fri Dec 24 15:23:01 2010 +0100
@@ -261,7 +261,10 @@
tmpfn = os.path.join(tmpdir, 'bundle')
try:
commands.bundle(ui, repo, tmpfn, dest, **opts)
- return open(tmpfn, 'rb').read()
+ fp = open(tmpfn, 'rb')
+ data = fp.read()
+ fp.close()
+ return data
finally:
try:
os.unlink(tmpfn)
--- a/mercurial/archival.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/archival.py Fri Dec 24 15:23:01 2010 +0100
@@ -84,6 +84,7 @@
def __init__(self, dest, mtime, kind=''):
self.mtime = mtime
+ self.fileobj = None
def taropen(name, mode, fileobj=None):
if kind == 'gz':
@@ -93,8 +94,10 @@
gzfileobj = self.GzipFileWithTime(name, mode + 'b',
zlib.Z_BEST_COMPRESSION,
fileobj, timestamp=mtime)
+ self.fileobj = gzfileobj
return tarfile.TarFile.taropen(name, mode, gzfileobj)
else:
+ self.fileobj = fileobj
return tarfile.open(name, mode + kind, fileobj)
if isinstance(dest, str):
@@ -120,6 +123,8 @@
def done(self):
self.z.close()
+ if self.fileobj:
+ self.fileobj.close()
class tellable(object):
'''provide tell method for zipfile.ZipFile when writing to http
--- a/mercurial/cmdutil.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/cmdutil.py Fri Dec 24 15:23:01 2010 +0100
@@ -679,7 +679,9 @@
parents.reverse()
prev = (parents and parents[0]) or nullid
+ shouldclose = False
if not fp:
+ shouldclose = True
fp = make_file(repo, template, node, total=total, seqno=seqno,
revwidth=revwidth, mode='ab')
if fp != sys.stdout and hasattr(fp, 'name'):
@@ -700,7 +702,8 @@
for chunk in patch.diff(repo, prev, node, opts=opts):
fp.write(chunk)
- fp.flush()
+ if shouldclose:
+ fp.close()
for seqno, rev in enumerate(revs):
single(rev, seqno + 1, fp)
--- a/mercurial/commands.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/commands.py Fri Dec 24 15:23:01 2010 +0100
@@ -750,6 +750,7 @@
if opts.get('decode'):
data = repo.wwritedata(abs, data)
fp.write(data)
+ fp.close()
err = 0
return err
--- a/mercurial/dirstate.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/dirstate.py Fri Dec 24 15:23:01 2010 +0100
@@ -80,7 +80,9 @@
@propertycache
def _pl(self):
try:
- st = self._opener("dirstate").read(40)
+ fp = self._opener("dirstate")
+ st = fp.read(40)
+ fp.close()
l = len(st)
if l == 40:
return st[:20], st[20:40]
--- a/mercurial/hgweb/common.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/hgweb/common.py Fri Dec 24 15:23:01 2010 +0100
@@ -119,7 +119,10 @@
os.stat(path)
ct = mimetypes.guess_type(path)[0] or "text/plain"
req.respond(HTTP_OK, ct, length = os.path.getsize(path))
- return open(path, 'rb').read()
+ fp = open(path, 'rb')
+ data = fp.read()
+ fp.close()
+ return data
except TypeError:
raise ErrorResponse(HTTP_SERVER_ERROR, 'illegal filename')
except OSError, err:
--- a/mercurial/localrepo.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/localrepo.py Fri Dec 24 15:23:01 2010 +0100
@@ -283,6 +283,8 @@
# committed tags are stored in UTF-8
writetags(fp, names, encoding.fromlocal, prevtags)
+ fp.close()
+
if '.hgtags' not in self.dirstate:
self[None].add(['.hgtags'])
--- a/mercurial/merge.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/merge.py Fri Dec 24 15:23:01 2010 +0100
@@ -32,6 +32,7 @@
else:
bits = l[:-1].split("\0")
self._state[bits[0]] = bits[1:]
+ f.close()
except IOError, err:
if err.errno != errno.ENOENT:
raise
@@ -42,6 +43,7 @@
f.write(hex(self._local) + "\n")
for d, v in self._state.iteritems():
f.write("\0".join([d] + v) + "\n")
+ f.close()
self._dirty = False
def add(self, fcl, fco, fca, fd, flags):
hash = util.sha1(fcl.path()).hexdigest()
@@ -67,6 +69,7 @@
state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
f = self._repo.opener("merge/" + hash)
self._repo.wwrite(dfile, f.read(), flags)
+ f.close()
fcd = wctx[dfile]
fco = octx[ofile]
fca = self._repo.filectx(afile, fileid=anode)
--- a/mercurial/posix.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/posix.py Fri Dec 24 15:23:01 2010 +0100
@@ -77,20 +77,26 @@
if l:
if not stat.S_ISLNK(s):
# switch file to link
- data = open(f).read()
+ fp = open(f)
+ data = fp.read()
+ fp.close()
os.unlink(f)
try:
os.symlink(data, f)
except:
# failed to make a link, rewrite file
- open(f, "w").write(data)
+ fp = open(f, "w")
+ fp.write(data)
+ fp.close()
# no chmod needed at this point
return
if stat.S_ISLNK(s):
# switch link to file
data = os.readlink(f)
os.unlink(f)
- open(f, "w").write(data)
+ fp = open(f, "w")
+ fp.write(data)
+ fp.close()
s = 0666 & ~umask # avoid restatting for chmod
sx = s & 0100
--- a/mercurial/revlog.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/revlog.py Fri Dec 24 15:23:01 2010 +0100
@@ -243,6 +243,7 @@
try:
f = self.opener(self.indexfile)
i = f.read()
+ f.close()
if len(i) > 0:
v = struct.unpack(versionformat, i[:4])[0]
except IOError, inst:
@@ -1167,6 +1168,7 @@
if not dfh and not self._inline:
# addrevision switched from inline to conventional
# reopen the index
+ ifh.close()
dfh = self.opener(self.datafile, "a")
ifh = self.opener(self.indexfile, "a")
finally:
@@ -1226,6 +1228,7 @@
f = self.opener(self.datafile)
f.seek(0, 2)
actual = f.tell()
+ f.close()
dd = actual - expected
except IOError, inst:
if inst.errno != errno.ENOENT:
@@ -1236,6 +1239,7 @@
f = self.opener(self.indexfile)
f.seek(0, 2)
actual = f.tell()
+ f.close()
s = self._io.size
i = max(0, actual // s)
di = actual - (i * s)
--- a/mercurial/statichttprepo.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/statichttprepo.py Fri Dec 24 15:23:01 2010 +0100
@@ -98,7 +98,9 @@
raise
# check if it is a non-empty old-style repository
try:
- self.opener("00changelog.i").read(1)
+ fp = self.opener("00changelog.i")
+ fp.read(1)
+ fp.close()
except IOError, inst:
if inst.errno != errno.ENOENT:
raise
--- a/mercurial/transaction.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/transaction.py Fri Dec 24 15:23:01 2010 +0100
@@ -27,13 +27,17 @@
for f, o, ignore in entries:
if o or not unlink:
try:
- opener(f, 'a').truncate(o)
+ fp = opener(f, 'a')
+ fp.truncate(o)
+ fp.close()
except IOError:
report(_("failed to truncate %s\n") % f)
raise
else:
try:
- fn = opener(f).name
+ fp = opener(f)
+ fn = fp.name
+ fp.close()
os.unlink(fn)
except (IOError, OSError), inst:
if inst.errno != errno.ENOENT:
@@ -169,7 +173,10 @@
def rollback(opener, file, report):
entries = []
- for l in open(file).readlines():
+ fp = open(file)
+ lines = fp.readlines()
+ fp.close()
+ for l in lines:
f, o = l.split('\0')
entries.append((f, int(o), None))
--- a/mercurial/util.py Fri Feb 11 22:24:10 2011 +0800
+++ b/mercurial/util.py Fri Dec 24 15:23:01 2010 +0100
@@ -198,7 +198,10 @@
if code:
raise Abort(_("command '%s' failed: %s") %
(cmd, explain_exit(code)))
- return open(outname, 'rb').read()
+ fp = open(outname, 'rb')
+ r = fp.read()
+ fp.close()
+ return r
finally:
try:
if inname:
@@ -591,7 +594,10 @@
raise
except AttributeError: # no symlink in os
pass
- return posixfile(pathname).read()
+ fp = posixfile(pathname)
+ r = fp.read()
+ fp.close()
+ return r
def fstat(fp):
'''stat file object that may not have fileno method.'''
--- a/setup.py Fri Feb 11 22:24:10 2011 +0800
+++ b/setup.py Fri Dec 24 15:23:01 2010 +0100
@@ -294,14 +294,18 @@
libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
for outfile in self.outfiles:
- data = open(outfile, 'rb').read()
+ fp = open(outfile, 'rb')
+ data = fp.read()
+ fp.close()
# skip binary files
if '\0' in data:
continue
data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
- open(outfile, 'wb').write(data)
+ fp = open(outfile, 'wb')
+ fp.write(data)
+ fp.close()
cmdclass = {'build_mo': hgbuildmo,
'build_ext': hgbuildext,
--- a/tests/run-tests.py Fri Feb 11 22:24:10 2011 +0800
+++ b/tests/run-tests.py Fri Dec 24 15:23:01 2010 +0100
@@ -231,6 +231,8 @@
if line and not line.startswith('#'):
blacklist[line] = filename
+ f.close()
+
options.blacklist = blacklist
return (options, args)
@@ -491,6 +493,8 @@
# non-command/result - queue up for merged output
after.setdefault(pos, []).append(l)
+ t.close()
+
script.append('echo %s %s $?\n' % (salt, n + 1))
fd, name = tempfile.mkstemp(suffix='hg-tst')
@@ -927,7 +931,9 @@
continue
if options.keywords:
- t = open(test).read().lower() + test.lower()
+ fp = open(test)
+ t = fp.read().lower() + test.lower()
+ fp.close()
for k in options.keywords.lower().split():
if k in t:
break