[PATCH 2 of 6] largefiles: use context for file closing
Mads Kiilerich
mads at kiilerich.com
Fri Oct 7 23:26:06 UTC 2016
# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1475881181 -7200
# Sat Oct 08 00:59:41 2016 +0200
# Node ID 87cea1040403001e660dd1c6b2e2d069d8a51d2e
# Parent 96315a5833ed015acb7bd8f6d7f1e38db6fa9c50
largefiles: use context for file closing
Make the code slightly smaller and safer (and more deeply indented).
diff --git a/hgext/largefiles/basestore.py b/hgext/largefiles/basestore.py
--- a/hgext/largefiles/basestore.py
+++ b/hgext/largefiles/basestore.py
@@ -91,15 +91,13 @@ class basestore(object):
storefilename = lfutil.storepath(self.repo, hash)
tmpname = storefilename + '.tmp'
- tmpfile = util.atomictempfile(tmpname,
- createmode=self.repo.store.createmode)
-
- try:
- gothash = self._getfile(tmpfile, filename, hash)
- except StoreError as err:
- self.ui.warn(err.longmessage())
- gothash = ""
- tmpfile.close()
+ with util.atomictempfile(tmpname,
+ createmode=self.repo.store.createmode) as tmpfile:
+ try:
+ gothash = self._getfile(tmpfile, filename, hash)
+ except StoreError as err:
+ self.ui.warn(err.longmessage())
+ gothash = ""
if gothash != hash:
if gothash != "":
diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
--- a/hgext/largefiles/lfutil.py
+++ b/hgext/largefiles/lfutil.py
@@ -54,10 +54,10 @@ def link(src, dest):
util.oslink(src, dest)
except OSError:
# if hardlinks fail, fallback on atomic copy
- dst = util.atomictempfile(dest)
- for chunk in util.filechunkiter(open(src, 'rb')):
- dst.write(chunk)
- dst.close()
+ with open(src, 'rb') as srcf:
+ with util.atomictempfile(dest) as dstf:
+ for chunk in util.filechunkiter(srcf):
+ dstf.write(chunk)
os.chmod(dest, os.stat(src).st_mode)
def usercachepath(ui, hash):
@@ -264,11 +264,11 @@ def copytostoreabsolute(repo, file, hash
link(usercachepath(repo.ui, hash), storepath(repo, hash))
else:
util.makedirs(os.path.dirname(storepath(repo, hash)))
- dst = util.atomictempfile(storepath(repo, hash),
- createmode=repo.store.createmode)
- for chunk in util.filechunkiter(open(file, 'rb')):
- dst.write(chunk)
- dst.close()
+ with open(file, 'rb') as srcf:
+ with util.atomictempfile(storepath(repo, hash),
+ createmode=repo.store.createmode) as dstf:
+ for chunk in util.filechunkiter(srcf):
+ dstf.write(chunk)
linktousercache(repo, hash)
def linktousercache(repo, hash):
@@ -370,10 +370,9 @@ def hashfile(file):
if not os.path.exists(file):
return ''
hasher = hashlib.sha1('')
- fd = open(file, 'rb')
- for data in util.filechunkiter(fd, 128 * 1024):
- hasher.update(data)
- fd.close()
+ with open(file, 'rb') as fd:
+ for data in util.filechunkiter(fd, 128 * 1024):
+ hasher.update(data)
return hasher.hexdigest()
def getexecutable(filename):
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -883,11 +883,8 @@ def hgclone(orig, ui, opts, *args, **kwa
# If largefiles is required for this repo, permanently enable it locally
if 'largefiles' in repo.requirements:
- fp = repo.vfs('hgrc', 'a', text=True)
- try:
+ with repo.vfs('hgrc', 'a', text=True) as fp:
fp.write('\n[extensions]\nlargefiles=\n')
- finally:
- fp.close()
# Caching is implicitly limited to 'rev' option, since the dest repo was
# truncated at that point. The user may expect a download count with
@@ -1339,30 +1336,28 @@ def overridecat(orig, ui, repo, file1, *
m.visitdir = lfvisitdirfn
for f in ctx.walk(m):
- fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
- pathname=f)
- lf = lfutil.splitstandin(f)
- if lf is None or origmatchfn(f):
- # duplicating unreachable code from commands.cat
- data = ctx[f].data()
- if opts.get('decode'):
- data = repo.wwritedata(f, data)
- fp.write(data)
- else:
- hash = lfutil.readstandin(repo, lf, ctx.rev())
- if not lfutil.inusercache(repo.ui, hash):
- store = storefactory.openstore(repo)
- success, missing = store.get([(lf, hash)])
- if len(success) != 1:
- raise error.Abort(
- _('largefile %s is not in cache and could not be '
- 'downloaded') % lf)
- path = lfutil.usercachepath(repo.ui, hash)
- fpin = open(path, "rb")
- for chunk in util.filechunkiter(fpin, 128 * 1024):
- fp.write(chunk)
- fpin.close()
- fp.close()
+ with cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
+ pathname=f) as fp:
+ lf = lfutil.splitstandin(f)
+ if lf is None or origmatchfn(f):
+ # duplicating unreachable code from commands.cat
+ data = ctx[f].data()
+ if opts.get('decode'):
+ data = repo.wwritedata(f, data)
+ fp.write(data)
+ else:
+ hash = lfutil.readstandin(repo, lf, ctx.rev())
+ if not lfutil.inusercache(repo.ui, hash):
+ store = storefactory.openstore(repo)
+ success, missing = store.get([(lf, hash)])
+ if len(success) != 1:
+ raise error.Abort(
+ _('largefile %s is not in cache and could not be '
+ 'downloaded') % lf)
+ path = lfutil.usercachepath(repo.ui, hash)
+ with open(path, "rb") as fpin:
+ for chunk in util.filechunkiter(fpin, 128 * 1024):
+ fp.write(chunk)
err = 0
return err
diff --git a/hgext/largefiles/remotestore.py b/hgext/largefiles/remotestore.py
--- a/hgext/largefiles/remotestore.py
+++ b/hgext/largefiles/remotestore.py
@@ -45,17 +45,13 @@ class remotestore(basestore.basestore):
def sendfile(self, filename, hash):
self.ui.debug('remotestore: sendfile(%s, %s)\n' % (filename, hash))
- fd = None
try:
- fd = lfutil.httpsendfile(self.ui, filename)
- return self._put(hash, fd)
+ with lfutil.httpsendfile(self.ui, filename) as fd:
+ return self._put(hash, fd)
except IOError as e:
raise error.Abort(
_('remotestore: could not open file %s: %s')
% (filename, str(e)))
- finally:
- if fd:
- fd.close()
def _getfile(self, tmpfile, filename, hash):
try:
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -499,6 +499,12 @@ class _unclosablefile(object):
def __getattr__(self, attr):
return getattr(self._fp, attr)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, exc_tb):
+ pass
+
def makefileobj(repo, pat, node=None, desc=None, total=None,
seqno=None, revwidth=None, mode='wb', modemap=None,
pathname=None):
diff --git a/mercurial/httpconnection.py b/mercurial/httpconnection.py
--- a/mercurial/httpconnection.py
+++ b/mercurial/httpconnection.py
@@ -58,6 +58,12 @@ class httpsendfile(object):
unit=_('kb'), total=self._total)
return ret
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.close()
+
# moved here from url.py to avoid a cycle
def readauthforuri(ui, uri, user):
# Read configuration
More information about the Mercurial-devel
mailing list