codemod: simplify nested withs
authorJun Wu <quark@fb.com>
Thu, 13 Jul 2017 18:31:35 -0700
changeset 33438 8056481caa81
parent 33437 0720e6265c8a
child 33439 0e114b992e02
codemod: simplify nested withs This is the result of running: python codemod_nestedwith.py **/*.py where codemod_nestedwith.py looks like this: #!/usr/bin/env python # codemod_nestedwith.py - codemod tool to rewrite nested with # # Copyright 2017 Facebook, Inc. # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import, print_function import sys import redbaron def readpath(path): with open(path) as f: return f.read() def writepath(path, content): with open(path, 'w') as f: f.write(content) def main(argv): if not argv: print('Usage: codemod_nestedwith.py FILES') for i, path in enumerate(argv): print('(%d/%d) scanning %s' % (i + 1, len(argv), path)) changed = False red = redbaron.RedBaron(readpath(path)) processed = set() for node in red.find_all('with'): if node in processed or node.type != 'with': continue top = node child = top[0] while True: if len(top) > 1 or child.type != 'with': break # estimate line length after merging two "with"s new = '%swith %s:' % (top.indentation, top.contexts.dumps()) new += ', %s' % child.contexts.dumps() # only do the rewrite if the end result is within 80 chars if len(new) > 80: break processed.add(child) top.contexts.extend(child.contexts) top.value = child.value top.value.decrease_indentation(4) child = child[0] changed = True if changed: print('updating %s' % path) writepath(path, red.dumps()) if __name__ == "__main__": sys.exit(main(sys.argv[1:])) Differential Revision: https://phab.mercurial-scm.org/D77
hgext/largefiles/lfutil.py
mercurial/cmdutil.py
mercurial/debugcommands.py
mercurial/upgrade.py
--- a/hgext/largefiles/lfutil.py	Mon Aug 08 18:14:42 2016 +0200
+++ b/hgext/largefiles/lfutil.py	Thu Jul 13 18:31:35 2017 -0700
@@ -58,10 +58,9 @@
         util.oslink(src, dest)
     except OSError:
         # if hardlinks fail, fallback on atomic copy
-        with open(src, 'rb') as srcf:
-            with util.atomictempfile(dest) as dstf:
-                for chunk in util.filechunkiter(srcf):
-                    dstf.write(chunk)
+        with open(src, 'rb') as srcf, 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):
@@ -236,10 +235,9 @@
     wvfs.makedirs(wvfs.dirname(wvfs.join(filename)))
     # The write may fail before the file is fully written, but we
     # don't use atomic writes in the working copy.
-    with open(path, 'rb') as srcfd:
-        with wvfs(filename, 'wb') as destfd:
-            gothash = copyandhash(
-                util.filechunkiter(srcfd), destfd)
+    with open(path, 'rb') as srcfd, wvfs(filename, 'wb') as destfd:
+        gothash = copyandhash(
+            util.filechunkiter(srcfd), destfd)
     if gothash != hash:
         repo.ui.warn(_('%s: data corruption in %s with hash %s\n')
                      % (filename, path, gothash))
--- a/mercurial/cmdutil.py	Mon Aug 08 18:14:42 2016 +0200
+++ b/mercurial/cmdutil.py	Thu Jul 13 18:31:35 2017 -0700
@@ -2750,148 +2750,147 @@
     base = old.p1()
 
     newid = None
-    with repo.wlock(), repo.lock():
-        with repo.transaction('amend') as tr:
-            # See if we got a message from -m or -l, if not, open the editor
-            # with the message of the changeset to amend
-            message = logmessage(ui, opts)
-            # ensure logfile does not conflict with later enforcement of the
-            # message. potential logfile content has been processed by
-            # `logmessage` anyway.
-            opts.pop('logfile')
-            # First, do a regular commit to record all changes in the working
-            # directory (if there are any)
-            ui.callhooks = False
-            activebookmark = repo._bookmarks.active
-            try:
-                repo._bookmarks.active = None
-                opts['message'] = 'temporary amend commit for %s' % old
-                node = commit(ui, repo, commitfunc, pats, opts)
-            finally:
-                repo._bookmarks.active = activebookmark
-                repo._bookmarks.recordchange(tr)
-                ui.callhooks = True
-            ctx = repo[node]
-
-            # Participating changesets:
+    with repo.wlock(), repo.lock(), repo.transaction('amend') as tr:
+        # See if we got a message from -m or -l, if not, open the editor
+        # with the message of the changeset to amend
+        message = logmessage(ui, opts)
+        # ensure logfile does not conflict with later enforcement of the
+        # message. potential logfile content has been processed by
+        # `logmessage` anyway.
+        opts.pop('logfile')
+        # First, do a regular commit to record all changes in the working
+        # directory (if there are any)
+        ui.callhooks = False
+        activebookmark = repo._bookmarks.active
+        try:
+            repo._bookmarks.active = None
+            opts['message'] = 'temporary amend commit for %s' % old
+            node = commit(ui, repo, commitfunc, pats, opts)
+        finally:
+            repo._bookmarks.active = activebookmark
+            repo._bookmarks.recordchange(tr)
+            ui.callhooks = True
+        ctx = repo[node]
+
+        # Participating changesets:
+        #
+        # node/ctx o - new (intermediate) commit that contains changes
+        #          |   from working dir to go into amending commit
+        #          |   (or a workingctx if there were no changes)
+        #          |
+        # old      o - changeset to amend
+        #          |
+        # base     o - parent of amending changeset
+
+        # Update extra dict from amended commit (e.g. to preserve graft
+        # source)
+        extra.update(old.extra())
+
+        # Also update it from the intermediate commit or from the wctx
+        extra.update(ctx.extra())
+
+        if len(old.parents()) > 1:
+            # ctx.files() isn't reliable for merges, so fall back to the
+            # slower repo.status() method
+            files = set([fn for st in repo.status(base, old)[:3]
+                         for fn in st])
+        else:
+            files = set(old.files())
+
+        # Second, we use either the commit we just did, or if there were no
+        # changes the parent of the working directory as the version of the
+        # files in the final amend commit
+        if node:
+            ui.note(_('copying changeset %s to %s\n') % (ctx, base))
+
+            user = ctx.user()
+            date = ctx.date()
+            # Recompute copies (avoid recording a -> b -> a)
+            copied = copies.pathcopies(base, ctx)
+            if old.p2:
+                copied.update(copies.pathcopies(old.p2(), ctx))
+
+            # Prune files which were reverted by the updates: if old
+            # introduced file X and our intermediate commit, node,
+            # renamed that file, then those two files are the same and
+            # we can discard X from our list of files. Likewise if X
+            # was deleted, it's no longer relevant
+            files.update(ctx.files())
+            files = [f for f in files if not samefile(f, ctx, base)]
+
+            def filectxfn(repo, ctx_, path):
+                try:
+                    fctx = ctx[path]
+                    flags = fctx.flags()
+                    mctx = context.memfilectx(repo,
+                                              fctx.path(), fctx.data(),
+                                              islink='l' in flags,
+                                              isexec='x' in flags,
+                                              copied=copied.get(path))
+                    return mctx
+                except KeyError:
+                    return None
+        else:
+            ui.note(_('copying changeset %s to %s\n') % (old, base))
+
+            # Use version of files as in the old cset
+            def filectxfn(repo, ctx_, path):
+                try:
+                    return old.filectx(path)
+                except KeyError:
+                    return None
+
+            user = opts.get('user') or old.user()
+            date = opts.get('date') or old.date()
+        editform = mergeeditform(old, 'commit.amend')
+        editor = getcommiteditor(editform=editform,
+                                 **pycompat.strkwargs(opts))
+        if not message:
+            editor = getcommiteditor(edit=True, editform=editform)
+            message = old.description()
+
+        pureextra = extra.copy()
+        extra['amend_source'] = old.hex()
+
+        new = context.memctx(repo,
+                             parents=[base.node(), old.p2().node()],
+                             text=message,
+                             files=files,
+                             filectxfn=filectxfn,
+                             user=user,
+                             date=date,
+                             extra=extra,
+                             editor=editor)
+
+        newdesc = changelog.stripdesc(new.description())
+        if ((not node)
+            and newdesc == old.description()
+            and user == old.user()
+            and date == old.date()
+            and pureextra == old.extra()):
+            # nothing changed. continuing here would create a new node
+            # anyway because of the amend_source noise.
             #
-            # node/ctx o - new (intermediate) commit that contains changes
-            #          |   from working dir to go into amending commit
-            #          |   (or a workingctx if there were no changes)
-            #          |
-            # old      o - changeset to amend
-            #          |
-            # base     o - parent of amending changeset
-
-            # Update extra dict from amended commit (e.g. to preserve graft
-            # source)
-            extra.update(old.extra())
-
-            # Also update it from the intermediate commit or from the wctx
-            extra.update(ctx.extra())
-
-            if len(old.parents()) > 1:
-                # ctx.files() isn't reliable for merges, so fall back to the
-                # slower repo.status() method
-                files = set([fn for st in repo.status(base, old)[:3]
-                             for fn in st])
+            # This not what we expect from amend.
+            return old.node()
+
+        ph = repo.ui.config('phases', 'new-commit', phases.draft)
+        try:
+            if opts.get('secret'):
+                commitphase = 'secret'
             else:
-                files = set(old.files())
-
-            # Second, we use either the commit we just did, or if there were no
-            # changes the parent of the working directory as the version of the
-            # files in the final amend commit
+                commitphase = old.phase()
+            repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
+            newid = repo.commitctx(new)
+        finally:
+            repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
+        if newid != old.node():
+            # Reroute the working copy parent to the new changeset
+            repo.setparents(newid, nullid)
+            mapping = {old.node(): (newid,)}
             if node:
-                ui.note(_('copying changeset %s to %s\n') % (ctx, base))
-
-                user = ctx.user()
-                date = ctx.date()
-                # Recompute copies (avoid recording a -> b -> a)
-                copied = copies.pathcopies(base, ctx)
-                if old.p2:
-                    copied.update(copies.pathcopies(old.p2(), ctx))
-
-                # Prune files which were reverted by the updates: if old
-                # introduced file X and our intermediate commit, node,
-                # renamed that file, then those two files are the same and
-                # we can discard X from our list of files. Likewise if X
-                # was deleted, it's no longer relevant
-                files.update(ctx.files())
-                files = [f for f in files if not samefile(f, ctx, base)]
-
-                def filectxfn(repo, ctx_, path):
-                    try:
-                        fctx = ctx[path]
-                        flags = fctx.flags()
-                        mctx = context.memfilectx(repo,
-                                                  fctx.path(), fctx.data(),
-                                                  islink='l' in flags,
-                                                  isexec='x' in flags,
-                                                  copied=copied.get(path))
-                        return mctx
-                    except KeyError:
-                        return None
-            else:
-                ui.note(_('copying changeset %s to %s\n') % (old, base))
-
-                # Use version of files as in the old cset
-                def filectxfn(repo, ctx_, path):
-                    try:
-                        return old.filectx(path)
-                    except KeyError:
-                        return None
-
-                user = opts.get('user') or old.user()
-                date = opts.get('date') or old.date()
-            editform = mergeeditform(old, 'commit.amend')
-            editor = getcommiteditor(editform=editform,
-                                     **pycompat.strkwargs(opts))
-            if not message:
-                editor = getcommiteditor(edit=True, editform=editform)
-                message = old.description()
-
-            pureextra = extra.copy()
-            extra['amend_source'] = old.hex()
-
-            new = context.memctx(repo,
-                                 parents=[base.node(), old.p2().node()],
-                                 text=message,
-                                 files=files,
-                                 filectxfn=filectxfn,
-                                 user=user,
-                                 date=date,
-                                 extra=extra,
-                                 editor=editor)
-
-            newdesc = changelog.stripdesc(new.description())
-            if ((not node)
-                and newdesc == old.description()
-                and user == old.user()
-                and date == old.date()
-                and pureextra == old.extra()):
-                # nothing changed. continuing here would create a new node
-                # anyway because of the amend_source noise.
-                #
-                # This not what we expect from amend.
-                return old.node()
-
-            ph = repo.ui.config('phases', 'new-commit', phases.draft)
-            try:
-                if opts.get('secret'):
-                    commitphase = 'secret'
-                else:
-                    commitphase = old.phase()
-                repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
-                newid = repo.commitctx(new)
-            finally:
-                repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
-            if newid != old.node():
-                # Reroute the working copy parent to the new changeset
-                repo.setparents(newid, nullid)
-                mapping = {old.node(): (newid,)}
-                if node:
-                    mapping[node] = ()
-                scmutil.cleanupnodes(repo, mapping, 'amend')
+                mapping[node] = ()
+            scmutil.cleanupnodes(repo, mapping, 'amend')
     return newid
 
 def commiteditor(repo, ctx, subs, editform=''):
--- a/mercurial/debugcommands.py	Mon Aug 08 18:14:42 2016 +0200
+++ b/mercurial/debugcommands.py	Thu Jul 13 18:31:35 2017 -0700
@@ -2177,9 +2177,8 @@
 @command('debugupdatecaches', [])
 def debugupdatecaches(ui, repo, *pats, **opts):
     """warm all known caches in the repository"""
-    with repo.wlock():
-        with repo.lock():
-            repo.updatecaches()
+    with repo.wlock(), repo.lock():
+        repo.updatecaches()
 
 @command('debugupgraderepo', [
     ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
--- a/mercurial/upgrade.py	Mon Aug 08 18:14:42 2016 +0200
+++ b/mercurial/upgrade.py	Thu Jul 13 18:31:35 2017 -0700
@@ -792,35 +792,33 @@
     upgradeactions = [a.name for a in actions]
 
     ui.write(_('beginning upgrade...\n'))
-    with repo.wlock():
-        with repo.lock():
-            ui.write(_('repository locked and read-only\n'))
-            # Our strategy for upgrading the repository is to create a new,
-            # temporary repository, write data to it, then do a swap of the
-            # data. There are less heavyweight ways to do this, but it is easier
-            # to create a new repo object than to instantiate all the components
-            # (like the store) separately.
-            tmppath = tempfile.mkdtemp(prefix='upgrade.', dir=repo.path)
-            backuppath = None
-            try:
-                ui.write(_('creating temporary repository to stage migrated '
-                           'data: %s\n') % tmppath)
-                dstrepo = localrepo.localrepository(repo.baseui,
-                                                    path=tmppath,
-                                                    create=True)
+    with repo.wlock(), repo.lock():
+        ui.write(_('repository locked and read-only\n'))
+        # Our strategy for upgrading the repository is to create a new,
+        # temporary repository, write data to it, then do a swap of the
+        # data. There are less heavyweight ways to do this, but it is easier
+        # to create a new repo object than to instantiate all the components
+        # (like the store) separately.
+        tmppath = tempfile.mkdtemp(prefix='upgrade.', dir=repo.path)
+        backuppath = None
+        try:
+            ui.write(_('creating temporary repository to stage migrated '
+                       'data: %s\n') % tmppath)
+            dstrepo = localrepo.localrepository(repo.baseui,
+                                                path=tmppath,
+                                                create=True)
 
-                with dstrepo.wlock():
-                    with dstrepo.lock():
-                        backuppath = _upgraderepo(ui, repo, dstrepo, newreqs,
-                                                  upgradeactions)
+            with dstrepo.wlock(), dstrepo.lock():
+                backuppath = _upgraderepo(ui, repo, dstrepo, newreqs,
+                                          upgradeactions)
 
-            finally:
-                ui.write(_('removing temporary repository %s\n') % tmppath)
-                repo.vfs.rmtree(tmppath, forcibly=True)
+        finally:
+            ui.write(_('removing temporary repository %s\n') % tmppath)
+            repo.vfs.rmtree(tmppath, forcibly=True)
 
-                if backuppath:
-                    ui.warn(_('copy of old repository backed up at %s\n') %
-                            backuppath)
-                    ui.warn(_('the old repository will not be deleted; remove '
-                              'it to free up disk space once the upgraded '
-                              'repository is verified\n'))
+            if backuppath:
+                ui.warn(_('copy of old repository backed up at %s\n') %
+                        backuppath)
+                ui.warn(_('the old repository will not be deleted; remove '
+                          'it to free up disk space once the upgraded '
+                          'repository is verified\n'))