# HG changeset patch # User Dan Villiom Podlaski Christiansen # Date 1304323878 -7200 # Node ID 135e244776f007d55619752bb863d4a6f3081984 # Parent 0e4753807c93a35f431610d64073610eb8942293 prevent transient leaks of file handle by using new helper functions These leaks may occur in environments that don't employ a reference counting GC, i.e. PyPy. This implies: - changing opener(...).read() calls to opener.read(...) - changing opener(...).write() calls to opener.write(...) - changing open(...).read(...) to util.readfile(...) - changing open(...).write(...) to util.writefile(...) diff -r 0e4753807c93 -r 135e244776f0 hgext/convert/darcs.py --- a/hgext/convert/darcs.py Mon May 02 10:11:05 2011 +0200 +++ b/hgext/convert/darcs.py Mon May 02 10:11:18 2011 +0200 @@ -191,7 +191,7 @@ if rev != self.lastrev: raise util.Abort(_('internal calling inconsistency')) path = os.path.join(self.tmppath, name) - data = open(path, 'rb').read() + data = util.readfile(path) mode = os.lstat(path).st_mode mode = (mode & 0111) and 'x' or '' return data, mode diff -r 0e4753807c93 -r 135e244776f0 hgext/convert/subversion.py --- a/hgext/convert/subversion.py Mon May 02 10:11:05 2011 +0200 +++ b/hgext/convert/subversion.py Mon May 02 10:11:18 2011 +0200 @@ -1028,7 +1028,7 @@ os.unlink(filename) except OSError: pass - self.wopener(filename, 'w').write(data) + self.wopener.write(filename, data) if self.is_exec: was_exec = self.is_exec(self.wjoin(filename)) diff -r 0e4753807c93 -r 135e244776f0 hgext/extdiff.py --- a/hgext/extdiff.py Mon May 02 10:11:05 2011 +0200 +++ b/hgext/extdiff.py Mon May 02 10:11:18 2011 +0200 @@ -97,7 +97,7 @@ if 'l' in fctx.flags(): wopener.symlink(data, wfn) else: - wopener(wfn, 'w').write(data) + wopener.write(wfn, data) if 'x' in fctx.flags(): util.set_flags(dest, False, True) if node is None: diff -r 0e4753807c93 -r 135e244776f0 hgext/gpg.py --- a/hgext/gpg.py Mon May 02 10:11:05 2011 +0200 +++ b/hgext/gpg.py Mon May 02 10:11:18 2011 +0200 @@ -234,7 +234,7 @@ # write it if opts['local']: - repo.opener("localsigs", "ab").write(sigmessage) + repo.opener.append("localsigs", sigmessage) return msigs = match.exact(repo.root, '', ['.hgsigs']) diff -r 0e4753807c93 -r 135e244776f0 hgext/keyword.py --- a/hgext/keyword.py Mon May 02 10:11:05 2011 +0200 +++ b/hgext/keyword.py Mon May 02 10:11:18 2011 +0200 @@ -413,7 +413,7 @@ demoitems('keywordset', ui.configitems('keywordset')) demoitems('keywordmaps', kwmaps.iteritems()) keywords = '$' + '$\n$'.join(sorted(kwmaps.keys())) + '$\n' - repo.wopener(fn, 'w').write(keywords) + repo.wopener.write(fn, keywords) repo[None].add([fn]) ui.note(_('\nkeywords written to %s:\n') % fn) ui.note(keywords) diff -r 0e4753807c93 -r 135e244776f0 hgext/mq.py --- a/hgext/mq.py Mon May 02 10:11:05 2011 +0200 +++ b/hgext/mq.py Mon May 02 10:11:18 2011 +0200 @@ -291,14 +291,14 @@ elif l.strip(): self.ui.warn(_('malformated mq status line: %s\n') % entry) # else we ignore empty lines - lines = self.opener(self.status_path).read().splitlines() + lines = self.opener.read(self.status_path).splitlines() return list(parselines(lines)) return [] @util.propertycache def full_series(self): if os.path.exists(self.join(self.series_path)): - return self.opener(self.series_path).read().splitlines() + return self.opener.read(self.series_path).splitlines() return [] @util.propertycache @@ -412,7 +412,7 @@ if self.active_guards is None: self.active_guards = [] try: - guards = self.opener(self.guards_path).read().split() + guards = self.opener.read(self.guards_path).split() except IOError, err: if err.errno != errno.ENOENT: raise diff -r 0e4753807c93 -r 135e244776f0 hgext/transplant.py --- a/hgext/transplant.py Mon May 02 10:11:05 2011 +0200 +++ b/hgext/transplant.py Mon May 02 10:11:18 2011 +0200 @@ -39,7 +39,7 @@ def read(self): abspath = os.path.join(self.path, self.transplantfile) if self.transplantfile and os.path.exists(abspath): - for line in self.opener(self.transplantfile).read().splitlines(): + for line in self.opener.read(self.transplantfile).splitlines(): lnode, rnode = map(revlog.bin, line.split(':')) list = self.transplants.setdefault(rnode, []) list.append(transplantentry(lnode, rnode)) @@ -318,7 +318,7 @@ nodes = [] merges = [] cur = nodes - for line in self.opener('series').read().splitlines(): + for line in self.opener.read('series').splitlines(): if line.startswith('# Merges'): cur = merges continue diff -r 0e4753807c93 -r 135e244776f0 mercurial/bookmarks.py --- a/mercurial/bookmarks.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/bookmarks.py Mon May 02 10:11:18 2011 +0200 @@ -72,12 +72,12 @@ refs = repo._bookmarks try: - bms = repo.opener('bookmarks').read() + bms = repo.opener.read('bookmarks') except IOError, inst: if inst.errno != errno.ENOENT: raise bms = '' - repo.opener('undo.bookmarks', 'w').write(bms) + repo.opener.write('undo.bookmarks', bms) if repo._bookmarkcurrent not in refs: setcurrent(repo, None) diff -r 0e4753807c93 -r 135e244776f0 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/cmdutil.py Mon May 02 10:11:18 2011 +0200 @@ -91,7 +91,7 @@ if logfile == '-': message = sys.stdin.read() else: - message = open(logfile).read() + message = util.readfile(logfile) except IOError, inst: raise util.Abort(_("can't read commit message '%s': %s") % (logfile, inst.strerror)) diff -r 0e4753807c93 -r 135e244776f0 mercurial/commands.py --- a/mercurial/commands.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/commands.py Mon May 02 10:11:18 2011 +0200 @@ -1129,7 +1129,7 @@ def debugfsinfo(ui, path = "."): """show information detected about current filesystem""" - open('.debugfsinfo', 'w').write('') + util.writefile('.debugfsinfo', '') ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no')) ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no')) ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo') @@ -2669,7 +2669,7 @@ raise util.Abort(_('no diffs found')) if msgs: - repo.opener('last-message.txt', 'wb').write('\n* * *\n'.join(msgs)) + repo.opener.write('last-message.txt', '\n* * *\n'.join(msgs)) finally: release(lock, wlock) diff -r 0e4753807c93 -r 135e244776f0 mercurial/dirstate.py --- a/mercurial/dirstate.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/dirstate.py Mon May 02 10:11:18 2011 +0200 @@ -74,7 +74,7 @@ @propertycache def _branch(self): try: - return self._opener("branch").read().strip() or "default" + return self._opener.read("branch").strip() or "default" except IOError: return "default" @@ -220,13 +220,13 @@ if branch in ['tip', '.', 'null']: raise util.Abort(_('the name \'%s\' is reserved') % branch) self._branch = encoding.fromlocal(branch) - self._opener("branch", "w").write(self._branch + '\n') + self._opener.write("branch", self._branch + '\n') def _read(self): self._map = {} self._copymap = {} try: - st = self._opener("dirstate").read() + st = self._opener.read("dirstate") except IOError, err: if err.errno != errno.ENOENT: raise diff -r 0e4753807c93 -r 135e244776f0 mercurial/filemerge.py --- a/mercurial/filemerge.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/filemerge.py Mon May 02 10:11:18 2011 +0200 @@ -113,14 +113,14 @@ def _matcheol(file, origfile): "Convert EOL markers in a file to match origfile" - tostyle = _eoltype(open(origfile, "rb").read()) + tostyle = _eoltype(util.readfile(origfile)) if tostyle: - data = open(file, "rb").read() + data = util.readfile(file) style = _eoltype(data) if style: newdata = data.replace(style, tostyle) if newdata != data: - open(file, "wb").write(newdata) + util.writefile(file, newdata) def filemerge(repo, mynode, orig, fcd, fco, fca): """perform a 3-way merge in the working directory diff -r 0e4753807c93 -r 135e244776f0 mercurial/help.py --- a/mercurial/help.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/help.py Mon May 02 10:11:18 2011 +0200 @@ -8,6 +8,7 @@ from i18n import gettext, _ import sys, os import extensions +import util def moduledoc(file): @@ -79,7 +80,7 @@ break path = os.path.join(docdir, topic + ".txt") - doc = gettext(open(path).read()) + doc = gettext(util.readfile(path)) for rewriter in helphooks.get(topic, []): doc = rewriter(topic, doc) return doc diff -r 0e4753807c93 -r 135e244776f0 mercurial/hg.py --- a/mercurial/hg.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/hg.py Mon May 02 10:11:18 2011 +0200 @@ -137,14 +137,14 @@ requirements = '' try: - requirements = srcrepo.opener('requires').read() + requirements = srcrepo.opener.read('requires') except IOError, inst: if inst.errno != errno.ENOENT: raise requirements += 'shared\n' - file(os.path.join(roothg, 'requires'), 'w').write(requirements) - file(os.path.join(roothg, 'sharedpath'), 'w').write(sharedpath) + util.writefile(os.path.join(roothg, 'requires'), requirements) + util.writefile(os.path.join(roothg, 'sharedpath'), sharedpath) r = repository(ui, root) diff -r 0e4753807c93 -r 135e244776f0 mercurial/localrepo.py --- a/mercurial/localrepo.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/localrepo.py Mon May 02 10:11:18 2011 +0200 @@ -56,7 +56,8 @@ if self.ui.configbool('format', 'dotencode', True): requirements.append('dotencode') # create an invalid changelog - self.opener("00changelog.i", "a").write( + self.opener.append( + "00changelog.i", '\0\0\0\2' # represents revlogv2 ' dummy changelog to prevent using the old repo layout' ) @@ -70,7 +71,7 @@ # find requirements requirements = set() try: - requirements = set(self.opener("requires").read().splitlines()) + requirements = set(self.opener.read("requires").splitlines()) except IOError, inst: if inst.errno != errno.ENOENT: raise @@ -80,7 +81,7 @@ self.sharedpath = self.path try: - s = os.path.realpath(self.opener("sharedpath").read()) + s = os.path.realpath(self.opener.read("sharedpath")) if not os.path.exists(s): raise error.RepoError( _('.hg/sharedpath points to nonexistent directory %s') % s) @@ -652,7 +653,7 @@ if self._link(filename): data = os.readlink(self.wjoin(filename)) else: - data = self.wopener(filename, 'r').read() + data = self.wopener.read(filename) return self._filter(self._encodefilterpats, filename, data) def wwrite(self, filename, data, flags): @@ -660,7 +661,7 @@ if 'l' in flags: self.wopener.symlink(data, filename) else: - self.wopener(filename, 'w').write(data) + fp = self.wopener.write(filename, data) if 'x' in flags: util.set_flags(self.wjoin(filename), False, True) @@ -679,13 +680,14 @@ # save dirstate for rollback try: - ds = self.opener("dirstate").read() + ds = self.opener.read("dirstate") except IOError: ds = "" - self.opener("journal.dirstate", "w").write(ds) - self.opener("journal.branch", "w").write( - encoding.fromlocal(self.dirstate.branch())) - self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc)) + self.opener.write("journal.dirstate", ds) + self.opener.write("journal.branch", + encoding.fromlocal(self.dirstate.branch())) + self.opener.write("journal.desc", + "%d\n%s\n" % (len(self), desc)) renames = [(self.sjoin("journal"), self.sjoin("undo")), (self.join("journal.dirstate"), self.join("undo.dirstate")), @@ -720,7 +722,7 @@ lock = self.lock() if os.path.exists(self.sjoin("undo")): try: - args = self.opener("undo.desc", "r").read().splitlines() + args = self.opener.read("undo.desc").splitlines() if len(args) >= 3 and self.ui.verbose: desc = _("repository tip rolled back to revision %s" " (undo %s: %s)\n") % ( @@ -741,7 +743,7 @@ util.rename(self.join('undo.bookmarks'), self.join('bookmarks')) try: - branch = self.opener("undo.branch").read() + branch = self.opener.read("undo.branch") self.dirstate.setbranch(branch) except IOError: self.ui.warn(_("named branch could not be reset, " diff -r 0e4753807c93 -r 135e244776f0 mercurial/match.py --- a/mercurial/match.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/match.py Mon May 02 10:11:18 2011 +0200 @@ -275,7 +275,7 @@ elif kind in ('listfile', 'listfile0'): delimiter = kind == 'listfile0' and '\0' or '\n' try: - files = open(name, 'r').read().split(delimiter) + files = util.readfile(name).split(delimiter) files = [f for f in files if f] except EnvironmentError: raise util.Abort(_("unable to read file list (%s)") % name) diff -r 0e4753807c93 -r 135e244776f0 mercurial/merge.py --- a/mercurial/merge.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/merge.py Mon May 02 10:11:18 2011 +0200 @@ -47,7 +47,7 @@ self._dirty = False def add(self, fcl, fco, fca, fd, flags): hash = util.sha1(fcl.path()).hexdigest() - self._repo.opener("merge/" + hash, "w").write(fcl.data()) + self._repo.opener.write("merge/" + hash, fcl.data()) self._state[fd] = ['u', hash, fcl.path(), fca.path(), hex(fca.filenode()), fco.path(), flags] self._dirty = True diff -r 0e4753807c93 -r 135e244776f0 mercurial/minirst.py --- a/mercurial/minirst.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/minirst.py Mon May 02 10:11:18 2011 +0200 @@ -467,7 +467,7 @@ print return blocks - text = open(sys.argv[1]).read() + text = util.readfile(sys.argv[1]) blocks = debug(findblocks, text) blocks = debug(findliteralblocks, blocks) blocks, pruned = debug(prunecontainers, blocks, sys.argv[2:]) diff -r 0e4753807c93 -r 135e244776f0 mercurial/statichttprepo.py --- a/mercurial/statichttprepo.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/statichttprepo.py Mon May 02 10:11:18 2011 +0200 @@ -93,7 +93,7 @@ # find requirements try: - requirements = self.opener("requires").read().splitlines() + requirements = self.opener.read("requires").splitlines() except IOError, inst: if inst.errno != errno.ENOENT: raise diff -r 0e4753807c93 -r 135e244776f0 mercurial/tags.py --- a/mercurial/tags.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/tags.py Mon May 02 10:11:18 2011 +0200 @@ -60,7 +60,7 @@ def readlocaltags(ui, repo, alltags, tagtypes): '''Read local tags in repo. Update alltags and tagtypes.''' try: - data = repo.opener("localtags").read() + data = repo.opener.read("localtags") except IOError, inst: if inst.errno != errno.ENOENT: raise diff -r 0e4753807c93 -r 135e244776f0 mercurial/templater.py --- a/mercurial/templater.py Mon May 02 10:11:05 2011 +0200 +++ b/mercurial/templater.py Mon May 02 10:11:18 2011 +0200 @@ -311,7 +311,7 @@ '''Get the template for the given template name. Use a local cache.''' if not t in self.cache: try: - self.cache[t] = open(self.map[t][1]).read() + self.cache[t] = util.readfile(self.map[t][1]) except KeyError, inst: raise util.Abort(_('"%s" not in template map') % inst.args[0]) except IOError, inst: diff -r 0e4753807c93 -r 135e244776f0 tests/test-symlink-os-yes-fs-no.py --- a/tests/test-symlink-os-yes-fs-no.py Mon May 02 10:11:05 2011 +0200 +++ b/tests/test-symlink-os-yes-fs-no.py Mon May 02 10:11:18 2011 +0200 @@ -1,5 +1,5 @@ import os, sys, time -from mercurial import hg, ui, commands +from mercurial import hg, ui, commands, util TESTDIR = os.environ["TESTDIR"] BUNDLEPATH = os.path.join(TESTDIR, 'bundles', 'test-no-symlinks.hg') @@ -29,7 +29,7 @@ for f in 'test0/a.lnk', 'test0/d/b.lnk': os.unlink(f) fp = open(f, 'wb') - fp.write(open(f[:-4]).read()) + fp.write(util.readfile(f[:-4])) fp.close() # reload repository