changeset 13400:14f3795a5ed7

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.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Fri, 24 Dec 2010 15:23:01 +0100
parents eff102facb15
children 12773f1b7728
files contrib/check-code.py hgext/gpg.py hgext/inotify/linux/__init__.py hgext/mq.py hgext/patchbomb.py mercurial/archival.py mercurial/cmdutil.py mercurial/commands.py mercurial/dirstate.py mercurial/hgweb/common.py mercurial/localrepo.py mercurial/merge.py mercurial/posix.py mercurial/revlog.py mercurial/statichttprepo.py mercurial/transaction.py mercurial/util.py setup.py tests/run-tests.py
diffstat 19 files changed, 89 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- 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