Patchwork D7014: py3: define and use pycompat.iteritems() for hgext/

login
register
mail settings
Submitter phabricator
Date Oct. 7, 2019, 8:11 p.m.
Message ID <differential-rev-PHID-DREV-p4tnbkcdlzfedvqfk5d7-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/42076/
State Superseded
Headers show

Comments

phabricator - Oct. 7, 2019, 8:11 p.m.
indygreg created this revision.
Herald added a reviewer: durin42.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: martinvonz.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  .iteritems() -> .items() is the last source transform being performed.
  But it is also the most widely used.
  
  This commit adds a pycompat.iteritems symbol and imports it in place
  of .iteritems() for usage in hgext/. I chose to stop at just hgext/
  because the patch will be large and it is an easy boundary to stop at
  since we can disable source transformation on a per-package basis.
  
  There are places where the type does implement items() and we could
  call items() directly. However, this would require critical thought
  and I thought it would be easier to just blindly change the code. We
  know which call sites need to be audited in the future because they
  have "pycompat.iteritems."
  
  With this change, we no longer perform source transformation on
  hgext!

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D7014

AFFECTED FILES
  hgext/absorb.py
  hgext/convert/bzr.py
  hgext/convert/common.py
  hgext/convert/convcmd.py
  hgext/convert/cvs.py
  hgext/convert/cvsps.py
  hgext/convert/filemap.py
  hgext/convert/hg.py
  hgext/convert/monotone.py
  hgext/convert/subversion.py
  hgext/eol.py
  hgext/fastannotate/context.py
  hgext/fastannotate/protocol.py
  hgext/fix.py
  hgext/fsmonitor/__init__.py
  hgext/githelp.py
  hgext/hgk.py
  hgext/histedit.py
  hgext/infinitepush/__init__.py
  hgext/infinitepush/bundleparts.py
  hgext/infinitepush/sqlindexapi.py
  hgext/journal.py
  hgext/keyword.py
  hgext/largefiles/overrides.py
  hgext/largefiles/remotestore.py
  hgext/lfs/__init__.py
  hgext/lfs/pointer.py
  hgext/lfs/wrapper.py
  hgext/mq.py
  hgext/rebase.py
  hgext/releasenotes.py
  hgext/remotefilelog/__init__.py
  hgext/remotefilelog/basestore.py
  hgext/remotefilelog/datapack.py
  hgext/remotefilelog/historypack.py
  hgext/remotefilelog/remotefilelog.py
  hgext/remotefilelog/remotefilelogserver.py
  hgext/remotefilelog/repack.py
  hgext/remotefilelog/shallowrepo.py
  hgext/remotefilelog/shallowutil.py
  hgext/remotenames.py
  hgext/strip.py
  hgext/uncommit.py
  hgext/win32text.py
  mercurial/__init__.py
  mercurial/pycompat.py

CHANGE DETAILS




To: indygreg, durin42, martinvonz, #hg-reviewers
Cc: mjpieters, mercurial-devel

Patch

diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -338,6 +338,7 @@ 
         return [a.encode('latin-1') for a in ret]
 
     shlexquote = shlex.quote
+    iteritems = lambda x: x.items()
     itervalues = lambda x: x.values()
 
 else:
@@ -417,6 +418,7 @@ 
     ziplist = zip
     rawinput = raw_input
     getargspec = inspect.getargspec
+    iteritems = lambda x: x.iteritems()
     itervalues = lambda x: x.itervalues()
 
 isjython = sysplatform.startswith(b'java')
diff --git a/mercurial/__init__.py b/mercurial/__init__.py
--- a/mercurial/__init__.py
+++ b/mercurial/__init__.py
@@ -31,7 +31,7 @@ 
 
         def find_spec(self, fullname, path, target=None):
             # Only handle Mercurial-related modules.
-            if not fullname.startswith(('mercurial.', 'hgext.')):
+            if not fullname.startswith('mercurial.'):
                 return None
             # don't try to parse binary
             if fullname.startswith('mercurial.cext.'):
@@ -46,9 +46,6 @@ 
             # don't try and mangle it
             if fullname.startswith('mercurial.rustext'):
                 return None
-            # pywatchman is already dual-version clean, don't try and mangle it
-            if fullname.startswith('hgext.fsmonitor.pywatchman'):
-                return None
 
             # Try to find the module using other registered finders.
             spec = None
@@ -131,7 +128,7 @@ 
     # ``replacetoken`` or any mechanism that changes semantics of module
     # loading is changed. Otherwise cached bytecode may get loaded without
     # the new transformation mechanisms applied.
-    BYTECODEHEADER = b'HG\x00\x15'
+    BYTECODEHEADER = b'HG\x00\x16'
 
     class hgloader(importlib.machinery.SourceFileLoader):
         """Custom module loader that transforms source code.
diff --git a/hgext/win32text.py b/hgext/win32text.py
--- a/hgext/win32text.py
+++ b/hgext/win32text.py
@@ -209,7 +209,7 @@ 
 def reposetup(ui, repo):
     if not repo.local():
         return
-    for name, fn in _filters.iteritems():
+    for name, fn in pycompat.iteritems(_filters):
         repo.adddatafilter(name, fn)
 
 
diff --git a/hgext/uncommit.py b/hgext/uncommit.py
--- a/hgext/uncommit.py
+++ b/hgext/uncommit.py
@@ -78,7 +78,7 @@ 
     files = initialfiles - exclude
     # Filter copies
     copied = copiesmod.pathcopies(base, ctx)
-    copied = dict((dst, src) for dst, src in copied.iteritems() if dst in files)
+    copied = dict((dst, src) for dst, src in pycompat.iteritems(copied) if dst in files)
 
     def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()):
         if path not in contentctx:
diff --git a/hgext/strip.py b/hgext/strip.py
--- a/hgext/strip.py
+++ b/hgext/strip.py
@@ -206,7 +206,7 @@ 
             # a revision we have to only delete the bookmark and not strip
             # anything. revsets cannot detect that case.
             nodetobookmarks = {}
-            for mark, node in repomarks.iteritems():
+            for mark, node in pycompat.iteritems(repomarks):
                 nodetobookmarks.setdefault(node, []).append(mark)
             for marks in nodetobookmarks.values():
                 if bookmarks.issuperset(marks):
diff --git a/hgext/remotenames.py b/hgext/remotenames.py
--- a/hgext/remotenames.py
+++ b/hgext/remotenames.py
@@ -165,7 +165,7 @@ 
         if not self.loaded:
             self._load()
 
-        for k, vtup in self.potentialentries.iteritems():
+        for k, vtup in pycompat.iteritems(self.potentialentries):
             yield (k, [bin(vtup[0])])
 
     items = iteritems
@@ -202,7 +202,7 @@ 
         if not self._nodetobmarks:
             bmarktonodes = self.bmarktonodes()
             self._nodetobmarks = {}
-            for name, node in bmarktonodes.iteritems():
+            for name, node in pycompat.iteritems(bmarktonodes):
                 self._nodetobmarks.setdefault(node[0], []).append(name)
         return self._nodetobmarks
 
@@ -213,7 +213,7 @@ 
         if not self._nodetobranch:
             branchtonodes = self.branchtonodes()
             self._nodetobranch = {}
-            for name, nodes in branchtonodes.iteritems():
+            for name, nodes in pycompat.iteritems(branchtonodes):
                 for node in nodes:
                     self._nodetobranch.setdefault(node, []).append(name)
         return self._nodetobranch
@@ -223,7 +223,7 @@ 
             marktonodes = self.bmarktonodes()
             self._hoisttonodes = {}
             hoist += b'/'
-            for name, node in marktonodes.iteritems():
+            for name, node in pycompat.iteritems(marktonodes):
                 if name.startswith(hoist):
                     name = name[len(hoist) :]
                     self._hoisttonodes[name] = node
@@ -234,7 +234,7 @@ 
             marktonodes = self.bmarktonodes()
             self._nodetohoists = {}
             hoist += b'/'
-            for name, node in marktonodes.iteritems():
+            for name, node in pycompat.iteritems(marktonodes):
                 if name.startswith(hoist):
                     name = name[len(hoist) :]
                     self._nodetohoists.setdefault(node[0], []).append(name)
diff --git a/hgext/remotefilelog/shallowutil.py b/hgext/remotefilelog/shallowutil.py
--- a/hgext/remotefilelog/shallowutil.py
+++ b/hgext/remotefilelog/shallowutil.py
@@ -103,7 +103,7 @@ 
     """
     result = collections.defaultdict(lambda: 0)
     for dict in dicts:
-        for k, v in dict.iteritems():
+        for k, v in pycompat.iteritems(dict):
             result[k] += v
     return result
 
@@ -111,7 +111,7 @@ 
 def prefixkeys(dict, prefix):
     """Returns ``dict`` with ``prefix`` prepended to all its keys."""
     result = {}
-    for k, v in dict.iteritems():
+    for k, v in pycompat.iteritems(dict):
         result[prefix + k] = v
     return result
 
@@ -160,7 +160,7 @@ 
     length limit is exceeded
     """
     metabuf = b''
-    for k, v in sorted((metadict or {}).iteritems()):
+    for k, v in sorted(pycompat.iteritems((metadict or {}))):
         if len(k) != 1:
             raise error.ProgrammingError(b'packmeta: illegal key: %s' % k)
         if len(v) > 0xFFFE:
@@ -188,7 +188,7 @@ 
     and METAKEYFLAG will be dropped if its value is 0.
     """
     newmeta = {}
-    for k, v in (metadict or {}).iteritems():
+    for k, v in pycompat.iteritems(metadict or {}):
         expectedtype = _metaitemtypes.get(k, (bytes,))
         if not isinstance(v, expectedtype):
             raise error.ProgrammingError(b'packmeta: wrong type of key %s' % k)
@@ -209,7 +209,7 @@ 
     integers.
     """
     metadict = _parsepackmeta(metabuf)
-    for k, v in metadict.iteritems():
+    for k, v in pycompat.iteritems(metadict):
         if k in _metaitemtypes and int in _metaitemtypes[k]:
             metadict[k] = bin2int(v)
     return metadict
diff --git a/hgext/remotefilelog/shallowrepo.py b/hgext/remotefilelog/shallowrepo.py
--- a/hgext/remotefilelog/shallowrepo.py
+++ b/hgext/remotefilelog/shallowrepo.py
@@ -15,6 +15,7 @@ 
     error,
     localrepo,
     match,
+    pycompat,
     scmutil,
     sparse,
     util,
@@ -271,7 +272,7 @@ 
             mfrevlog = mfl.getstorage(b'')
             if base is not None:
                 mfdict = mfl[repo[base].manifestnode()].read()
-                skip = set(mfdict.iteritems())
+                skip = set(pycompat.iteritems(mfdict))
             else:
                 skip = set()
 
@@ -301,7 +302,7 @@ 
                 else:
                     mfdict = mfl[mfnode].read()
 
-                diff = mfdict.iteritems()
+                diff = pycompat.iteritems(mfdict)
                 if pats:
                     diff = (pf for pf in diff if m(pf[0]))
                 if sparsematch:
diff --git a/hgext/remotefilelog/repack.py b/hgext/remotefilelog/repack.py
--- a/hgext/remotefilelog/repack.py
+++ b/hgext/remotefilelog/repack.py
@@ -491,12 +491,12 @@ 
         if type(m) is dict:
             # m is a result of diff of two manifests and is a dictionary that
             # maps filename to ((newnode, newflag), (oldnode, oldflag)) tuple
-            for filename, diff in m.iteritems():
+            for filename, diff in pycompat.iteritems(m):
                 if diff[0][0] is not None:
                     keepkeys.add(keyfn(filename, diff[0][0]))
         else:
             # m is a manifest object
-            for filename, filenode in m.iteritems():
+            for filename, filenode in pycompat.iteritems(m):
                 keepkeys.add(keyfn(filename, filenode))
 
     return keepkeys
@@ -606,7 +606,7 @@ 
         repackprogress = ui.makeprogress(
             _(b"repacking data"), unit=self.unit, total=len(byfile)
         )
-        for filename, entries in sorted(byfile.iteritems()):
+        for filename, entries in sorted(pycompat.iteritems(byfile)):
             repackprogress.update(count)
 
             ancestors = {}
@@ -760,7 +760,7 @@ 
         progress = ui.makeprogress(
             _(b"repacking history"), unit=self.unit, total=len(byfile)
         )
-        for filename, entries in sorted(byfile.iteritems()):
+        for filename, entries in sorted(pycompat.iteritems(byfile)):
             ancestors = {}
             nodes = list(node for node in entries)
 
diff --git a/hgext/remotefilelog/remotefilelogserver.py b/hgext/remotefilelog/remotefilelogserver.py
--- a/hgext/remotefilelog/remotefilelogserver.py
+++ b/hgext/remotefilelog/remotefilelogserver.py
@@ -22,6 +22,7 @@ 
     error,
     extensions,
     match,
+    pycompat,
     store,
     streamclone,
     util,
@@ -417,7 +418,7 @@ 
     cachepath = repo.vfs.join(b"remotefilelogcache")
     for head in heads:
         mf = repo[head].manifest()
-        for filename, filenode in mf.iteritems():
+        for filename, filenode in pycompat.iteritems(mf):
             filecachepath = os.path.join(cachepath, filename, hex(filenode))
             neededfiles.add(filecachepath)
 
diff --git a/hgext/remotefilelog/remotefilelog.py b/hgext/remotefilelog/remotefilelog.py
--- a/hgext/remotefilelog/remotefilelog.py
+++ b/hgext/remotefilelog/remotefilelog.py
@@ -21,6 +21,7 @@ 
     ancestor,
     error,
     mdiff,
+    pycompat,
     revlog,
     util,
 )
@@ -428,7 +429,7 @@ 
             return nullid
 
         revmap, parentfunc = self._buildrevgraph(a, b)
-        nodemap = dict(((v, k) for (k, v) in revmap.iteritems()))
+        nodemap = dict(((v, k) for (k, v) in pycompat.iteritems(revmap)))
 
         ancs = ancestor.ancestors(parentfunc, revmap[a], revmap[b])
         if ancs:
@@ -443,7 +444,7 @@ 
             return nullid
 
         revmap, parentfunc = self._buildrevgraph(a, b)
-        nodemap = dict(((v, k) for (k, v) in revmap.iteritems()))
+        nodemap = dict(((v, k) for (k, v) in pycompat.iteritems(revmap)))
 
         ancs = ancestor.commonancestorsheads(parentfunc, revmap[a], revmap[b])
         return map(nodemap.__getitem__, ancs)
@@ -459,7 +460,7 @@ 
         parentsmap = collections.defaultdict(list)
         allparents = set()
         for mapping in (amap, bmap):
-            for node, pdata in mapping.iteritems():
+            for node, pdata in pycompat.iteritems(mapping):
                 parents = parentsmap[node]
                 p1, p2, linknode, copyfrom = pdata
                 # Don't follow renames (copyfrom).
diff --git a/hgext/remotefilelog/historypack.py b/hgext/remotefilelog/historypack.py
--- a/hgext/remotefilelog/historypack.py
+++ b/hgext/remotefilelog/historypack.py
@@ -518,7 +518,7 @@ 
 
         files = (
             (hashlib.sha1(filename).digest(), filename, offset, size)
-            for filename, (offset, size) in self.files.iteritems()
+            for filename, (offset, size) in pycompat.iteritems(self.files)
         )
         files = sorted(files)
 
@@ -554,7 +554,7 @@ 
             )
             nodeindexoffset += constants.FILENAMESIZE + len(filename)
 
-            for node, location in sorted(nodelocations.iteritems()):
+            for node, location in sorted(pycompat.iteritems(nodelocations)):
                 nodeindexentries.append(
                     struct.pack(nodeindexformat, node, location)
                 )
diff --git a/hgext/remotefilelog/datapack.py b/hgext/remotefilelog/datapack.py
--- a/hgext/remotefilelog/datapack.py
+++ b/hgext/remotefilelog/datapack.py
@@ -452,7 +452,7 @@ 
 
     def createindex(self, nodelocations, indexoffset):
         entries = sorted(
-            (n, db, o, s) for n, (db, o, s) in self.entries.iteritems()
+            (n, db, o, s) for n, (db, o, s) in pycompat.iteritems(self.entries)
         )
 
         rawindex = b''
diff --git a/hgext/remotefilelog/basestore.py b/hgext/remotefilelog/basestore.py
--- a/hgext/remotefilelog/basestore.py
+++ b/hgext/remotefilelog/basestore.py
@@ -148,7 +148,7 @@ 
 
         filenamemap = self._resolvefilenames(existing.keys())
 
-        for filename, sha in filenamemap.iteritems():
+        for filename, sha in pycompat.iteritems(filenamemap):
             yield (filename, existing[sha])
 
     def _resolvefilenames(self, hashes):
diff --git a/hgext/remotefilelog/__init__.py b/hgext/remotefilelog/__init__.py
--- a/hgext/remotefilelog/__init__.py
+++ b/hgext/remotefilelog/__init__.py
@@ -502,7 +502,7 @@ 
     if isenabled(repo):
         files = []
         sparsematch = repo.maybesparsematch(mctx.rev())
-        for f, (m, actionargs, msg) in actions.iteritems():
+        for f, (m, actionargs, msg) in pycompat.iteritems(actions):
             if sparsematch and not sparsematch(f):
                 continue
             if m in (b'c', b'dc', b'cm'):
diff --git a/hgext/releasenotes.py b/hgext/releasenotes.py
--- a/hgext/releasenotes.py
+++ b/hgext/releasenotes.py
@@ -161,7 +161,7 @@ 
             custom_sections = getcustomadmonitions(repo)
             if custom_sections:
                 sections.update(custom_sections)
-            self._sections = list(sections.iteritems())
+            self._sections = list(pycompat.iteritems(sections))
         else:
             self._sections = list(DEFAULT_SECTIONS)
 
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -151,7 +151,7 @@ 
     )
     repo = ctx.repo()
     names = []
-    for nsname, ns in repo.names.iteritems():
+    for nsname, ns in pycompat.iteritems(repo.names):
         if nsname == b'branches':
             continue
         names.extend(ns.names(repo, ctx.node()))
@@ -239,7 +239,7 @@ 
         f.write(b'%d\n' % int(self.keepbranchesf))
         f.write(b'%s\n' % (self.activebookmark or b''))
         destmap = self.destmap
-        for d, v in self.state.iteritems():
+        for d, v in pycompat.iteritems(self.state):
             oldrev = repo[d].hex()
             if v >= 0:
                 newrev = repo[v].hex()
@@ -489,7 +489,7 @@ 
             # commits.
             self.storestatus(tr)
 
-        cands = [k for k, v in self.state.iteritems() if v == revtodo]
+        cands = [k for k, v in pycompat.iteritems(self.state) if v == revtodo]
         p = repo.ui.makeprogress(
             _(b"rebasing"), unit=_(b'changesets'), total=len(cands)
         )
@@ -1326,7 +1326,7 @@ 
             # emulate the old behavior, showing "nothing to rebase" (a better
             # behavior may be abort with "cannot find branching point" error)
             bpbase.clear()
-        for bp, bs in bpbase.iteritems():  # calculate roots
+        for bp, bs in pycompat.iteritems(bpbase):  # calculate roots
             roots += list(repo.revs(b'children(%d) & ancestors(%ld)', bp, bs))
 
         rebaseset = repo.revs(b'%ld::', roots)
@@ -1970,7 +1970,7 @@ 
 
     # We should be standing on the first as-of-yet unrebased commit.
     firstunrebased = min(
-        [old for old, new in state.iteritems() if new == nullrev]
+        [old for old, new in pycompat.iteritems(state) if new == nullrev]
     )
     if firstunrebased in parents:
         return True
@@ -2121,7 +2121,7 @@ 
         fl = fm.formatlist
         fd = fm.formatdict
         changes = {}
-        for oldns, newn in replacements.iteritems():
+        for oldns, newn in pycompat.iteritems(replacements):
             for oldn in oldns:
                 changes[hf(oldn)] = fl([hf(n) for n in newn], name=b'node')
         nodechanges = fd(changes, key=b"oldnode", value=b"newnodes")
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -2001,7 +2001,7 @@ 
                         # we can't copy a file created by the patch itself
                         if dst in copies:
                             del copies[dst]
-                    for src, dsts in copies.iteritems():
+                    for src, dsts in pycompat.iteritems(copies):
                         for dst in dsts:
                             repo.dirstate.copy(src, dst)
                 else:
@@ -4263,7 +4263,7 @@ 
     entry[1].extend(mqopt)
 
     def dotable(cmdtable):
-        for cmd, entry in cmdtable.iteritems():
+        for cmd, entry in pycompat.iteritems(cmdtable):
             cmd = cmdutil.parsealiases(cmd)[0]
             func = entry[0]
             if func.norepo:
diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py
--- a/hgext/lfs/wrapper.py
+++ b/hgext/lfs/wrapper.py
@@ -25,6 +25,7 @@ 
     exchange,
     exthelper,
     localrepo,
+    pycompat,
     revlog,
     scmutil,
     upgrade,
@@ -138,7 +139,7 @@ 
 
     # translate hg filelog metadata to lfs metadata with "x-hg-" prefix
     if hgmeta is not None:
-        for k, v in hgmeta.iteritems():
+        for k, v in pycompat.iteritems(hgmeta):
             metadata[b'x-hg-%s' % k] = v
 
     rawtext = metadata.serialize()
diff --git a/hgext/lfs/pointer.py b/hgext/lfs/pointer.py
--- a/hgext/lfs/pointer.py
+++ b/hgext/lfs/pointer.py
@@ -41,7 +41,7 @@ 
 
     def serialize(self):
         sortkeyfunc = lambda x: (x[0] != b'version', x)
-        items = sorted(self.validate().iteritems(), key=sortkeyfunc)
+        items = sorted(pycompat.iteritems(self.validate()), key=sortkeyfunc)
         return b''.join(b'%s %s\n' % (k, v) for k, v in items)
 
     def oid(self):
@@ -63,7 +63,7 @@ 
     def validate(self):
         """raise InvalidPointer on error. return self if there is no error"""
         requiredcount = 0
-        for k, v in self.iteritems():
+        for k, v in pycompat.iteritems(self):
             if k in self._requiredre:
                 if not self._requiredre[k].match(v):
                     raise InvalidPointer(
diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -381,7 +381,7 @@ 
     def pointer(v):
         # In the file spec, version is first and the other keys are sorted.
         sortkeyfunc = lambda x: (x[0] != b'version', x)
-        items = sorted(pointers[v].iteritems(), key=sortkeyfunc)
+        items = sorted(pycompat.iteritems(pointers[v]), key=sortkeyfunc)
         return util.sortdict(items)
 
     makemap = lambda v: {
diff --git a/hgext/largefiles/remotestore.py b/hgext/largefiles/remotestore.py
--- a/hgext/largefiles/remotestore.py
+++ b/hgext/largefiles/remotestore.py
@@ -11,6 +11,7 @@ 
 
 from mercurial import (
     error,
+    pycompat,
     util,
 )
 
@@ -49,7 +50,7 @@ 
     def exists(self, hashes):
         return dict(
             (h, s == 0)
-            for (h, s) in self._stat(hashes).iteritems()  # dict-from-generator
+            for (h, s) in pycompat.iteritems(self._stat(hashes))  # dict-from-generator
         )
 
     def sendfile(self, filename, hash):
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -688,7 +688,7 @@ 
     copies = orig(ctx1, ctx2, match=match)
     updated = {}
 
-    for k, v in copies.iteritems():
+    for k, v in pycompat.iteritems(copies):
         updated[lfutil.splitstandin(k) or k] = lfutil.splitstandin(v) or v
 
     return updated
diff --git a/hgext/keyword.py b/hgext/keyword.py
--- a/hgext/keyword.py
+++ b/hgext/keyword.py
@@ -507,7 +507,7 @@ 
         kwmaps = _defaultkwmaps(ui)
         if uikwmaps:
             ui.status(_(b'\tdisabling current template maps\n'))
-            for k, v in kwmaps.iteritems():
+            for k, v in pycompat.iteritems(kwmaps):
                 ui.setconfig(b'keywordmaps', k, v, b'keyword')
     else:
         ui.status(_(b'\n\tconfiguration using current keyword template maps\n'))
@@ -521,7 +521,7 @@ 
     ui.writenoi18n(b'[extensions]\nkeyword =\n')
     demoitems(b'keyword', ui.configitems(b'keyword'))
     demoitems(b'keywordset', ui.configitems(b'keywordset'))
-    demoitems(b'keywordmaps', kwmaps.iteritems())
+    demoitems(b'keywordmaps', pycompat.iteritems(kwmaps))
     keywords = b'$' + b'$\n$'.join(sorted(kwmaps.keys())) + b'$\n'
     repo.wvfs.write(fn, keywords)
     repo[None].add([fn])
diff --git a/hgext/journal.py b/hgext/journal.py
--- a/hgext/journal.py
+++ b/hgext/journal.py
@@ -126,7 +126,7 @@ 
     repo = store._repo
     if util.safehasattr(repo, b'journal'):
         oldmarks = bookmarks.bmstore(repo)
-        for mark, value in store.iteritems():
+        for mark, value in pycompat.iteritems(store):
             oldvalue = oldmarks.get(mark, node.nullid)
             if value != oldvalue:
                 repo.journal.record(bookmarktype, mark, oldvalue, value)
diff --git a/hgext/infinitepush/sqlindexapi.py b/hgext/infinitepush/sqlindexapi.py
--- a/hgext/infinitepush/sqlindexapi.py
+++ b/hgext/infinitepush/sqlindexapi.py
@@ -14,9 +14,10 @@ 
 import warnings
 import mysql.connector
 
+from mercurial import pycompat
+
 from . import indexapi
 
-
 def _convertbookmarkpattern(pattern):
     pattern = pattern.replace(b'_', b'\\_')
     pattern = pattern.replace(b'%', b'\\%')
@@ -178,7 +179,7 @@ 
             self.sqlconnect()
         args = []
         values = []
-        for bookmark, node in bookmarks.iteritems():
+        for bookmark, node in pycompat.iteritems(bookmarks):
             args.append(b'(%s, %s, %s)')
             values.extend((bookmark, node, self.reponame))
         args = b','.join(args)
diff --git a/hgext/infinitepush/bundleparts.py b/hgext/infinitepush/bundleparts.py
--- a/hgext/infinitepush/bundleparts.py
+++ b/hgext/infinitepush/bundleparts.py
@@ -13,6 +13,7 @@ 
     error,
     extensions,
     node as nodemod,
+    pycompat,
     revsetlang,
     util,
 )
@@ -67,7 +68,7 @@ 
     parts.append(
         bundle2.bundlepart(
             scratchbranchparttype.upper(),
-            advisoryparams=params.iteritems(),
+            advisoryparams=pycompat.iteritems(params),
             data=cg,
         )
     )
diff --git a/hgext/infinitepush/__init__.py b/hgext/infinitepush/__init__.py
--- a/hgext/infinitepush/__init__.py
+++ b/hgext/infinitepush/__init__.py
@@ -378,7 +378,7 @@ 
 
 def wireprotolistkeyspatterns(repo, proto, namespace, patterns):
     patterns = wireprototypes.decodelist(patterns)
-    d = repo.listkeys(encoding.tolocal(namespace), patterns).iteritems()
+    d = pycompat.iteritems(repo.listkeys(encoding.tolocal(namespace), patterns))
     return pushkey.encodekeys(d)
 
 
@@ -392,7 +392,7 @@ 
             if pattern.endswith(b'*'):
                 pattern = b're:^' + pattern[:-1] + b'.*'
             kind, pat, matcher = stringutil.stringmatcher(pattern)
-            for bookmark, node in bookmarks.iteritems():
+            for bookmark, node in pycompat.iteritems(bookmarks):
                 if matcher(bookmark):
                     results[bookmark] = node
         return results
@@ -514,7 +514,7 @@ 
                     if part.type == b'changegroup':
                         haschangegroup = True
                     newpart = bundle2.bundlepart(part.type, data=part.read())
-                    for key, value in part.params.iteritems():
+                    for key, value in pycompat.iteritems(part.params):
                         newpart.addparam(key, value)
                     parts.append(newpart)
 
@@ -757,7 +757,7 @@ 
             # saveremotenames expects 20 byte binary nodes for branches
             branches[rname].append(bin(hexnode))
 
-    for bookmark, hexnode in newbookmarks.iteritems():
+    for bookmark, hexnode in pycompat.iteritems(newbookmarks):
         bookmarks[bookmark] = hexnode
     remotenamesext.saveremotenames(repo, remotepath, branches, bookmarks)
 
@@ -767,7 +767,7 @@ 
         return
     with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
         changes = []
-        for scratchbook, node in bookmarks.iteritems():
+        for scratchbook, node in pycompat.iteritems(bookmarks):
             changectx = repo[node]
             changes.append((scratchbook, changectx.node()))
         repo._bookmarks.applychanges(repo, tr, changes)
@@ -1005,7 +1005,7 @@ 
                 bundle2._processpart(op, part)
             else:
                 bundlepart = bundle2.bundlepart(part.type, data=part.read())
-                for key, value in part.params.iteritems():
+                for key, value in pycompat.iteritems(part.params):
                     bundlepart.addparam(key, value)
 
                 # Certain parts require a response
@@ -1092,7 +1092,7 @@ 
                     # differs from previous behavior, we need to put it behind a
                     # config flag for incremental rollout.
                     bundlepart = bundle2.bundlepart(part.type, data=part.read())
-                    for key, value in part.params.iteritems():
+                    for key, value in pycompat.iteritems(part.params):
                         bundlepart.addparam(key, value)
 
                     # Certain parts require a response
@@ -1273,7 +1273,7 @@ 
                 b'new': newnode,
                 b'old': oldnode,
             }
-            op.reply.newpart(b'pushkey', mandatoryparams=params.iteritems())
+            op.reply.newpart(b'pushkey', mandatoryparams=pycompat.iteritems(params))
 
 
 def bundle2pushkey(orig, op, part):
diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -2013,7 +2013,7 @@ 
 
     mapping, tmpnodes, created, ntm = processreplacement(state)
     if mapping:
-        for prec, succs in mapping.iteritems():
+        for prec, succs in pycompat.iteritems(mapping):
             if not succs:
                 ui.debug(b'histedit: %s is dropped\n' % node.short(prec))
             else:
@@ -2051,7 +2051,7 @@ 
     nodechanges = fd(
         {
             hf(oldn): fl([hf(n) for n in newn], name=b'node')
-            for oldn, newn in mapping.iteritems()
+            for oldn, newn in pycompat.iteritems(mapping)
         },
         key=b"oldnode",
         value=b"newnodes",
@@ -2311,7 +2311,7 @@ 
                     tsum = summary[len(fword) + 1 :].lstrip()
                     # safe but slow: reverse iterate over the actions so we
                     # don't clash on two commits having the same summary
-                    for na, l in reversed(list(newact.iteritems())):
+                    for na, l in reversed(list(pycompat.iteritems(newact))):
                         actx = repo[na.node]
                         asum = _getsummary(actx)
                         if asum == tsum:
@@ -2324,7 +2324,7 @@ 
 
         # copy over and flatten the new list
         actions = []
-        for na, l in newact.iteritems():
+        for na, l in pycompat.iteritems(newact):
             actions.append(na)
             actions += l
 
diff --git a/hgext/hgk.py b/hgext/hgk.py
--- a/hgext/hgk.py
+++ b/hgext/hgk.py
@@ -376,7 +376,7 @@ 
     b"start interactive history viewer"
     opts = pycompat.byteskwargs(opts)
     os.chdir(repo.root)
-    optstr = b' '.join([b'--%s %s' % (k, v) for k, v in opts.iteritems() if v])
+    optstr = b' '.join([b'--%s %s' % (k, v) for k, v in pycompat.iteritems(opts) if v])
     if repo.filtername is None:
         optstr += b'--hidden'
 
diff --git a/hgext/githelp.py b/hgext/githelp.py
--- a/hgext/githelp.py
+++ b/hgext/githelp.py
@@ -116,7 +116,7 @@ 
     opts = dict(
         [
             (k, convert(v)) if isinstance(v, str) else (k, v)
-            for k, v in opts.iteritems()
+            for k, v in pycompat.iteritems(opts)
         ]
     )
 
@@ -132,7 +132,7 @@ 
     def __bytes__(self):
         cmd = b"hg " + self.name
         if self.opts:
-            for k, values in sorted(self.opts.iteritems()):
+            for k, values in sorted(pycompat.iteritems(self.opts)):
                 for v in values:
                     if v:
                         if isinstance(v, int):
diff --git a/hgext/fsmonitor/__init__.py b/hgext/fsmonitor/__init__.py
--- a/hgext/fsmonitor/__init__.py
+++ b/hgext/fsmonitor/__init__.py
@@ -467,12 +467,12 @@ 
             visit.update(f for f in copymap if f not in results and matchfn(f))
     else:
         if matchalways:
-            visit.update(f for f, st in dmap.iteritems() if f not in results)
+            visit.update(f for f, st in pycompat.iteritems(dmap) if f not in results)
             visit.update(f for f in copymap if f not in results)
         else:
             visit.update(
                 f
-                for f, st in dmap.iteritems()
+                for f, st in pycompat.iteritems(dmap)
                 if f not in results and matchfn(f)
             )
             visit.update(f for f in copymap if f not in results and matchfn(f))
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -353,7 +353,7 @@ 
     Useful as a hook point for extending "hg fix" with output summarizing the
     effects of the command, though we choose not to output anything here.
     """
-    replacements = {prec: [succ] for prec, succ in replacements.iteritems()}
+    replacements = {prec: [succ] for prec, succ in pycompat.iteritems(replacements)}
     scmutil.cleanupnodes(repo, replacements, b'fix', fixphase=True)
 
 
@@ -619,7 +619,7 @@ 
     """
     metadata = {}
     newdata = fixctx[path].data()
-    for fixername, fixer in fixers.iteritems():
+    for fixername, fixer in pycompat.iteritems(fixers):
         if fixer.affects(opts, fixctx, path):
             ranges = lineranges(opts, path, basectxs, fixctx, newdata)
             command = fixer.command(ui, path, ranges)
@@ -695,7 +695,7 @@ 
 
     Directly updates the dirstate for the affected files.
     """
-    for path, data in filedata.iteritems():
+    for path, data in pycompat.iteritems(filedata):
         fctx = ctx[path]
         fctx.write(data, fctx.flags())
         if repo.dirstate[path] == b'n':
diff --git a/hgext/fastannotate/protocol.py b/hgext/fastannotate/protocol.py
--- a/hgext/fastannotate/protocol.py
+++ b/hgext/fastannotate/protocol.py
@@ -15,6 +15,7 @@ 
     error,
     extensions,
     hg,
+    pycompat,
     util,
     wireprotov1peer,
     wireprotov1server,
@@ -188,7 +189,7 @@ 
         for result in results:
             r = result.result()
             # TODO: pconvert these paths on the server?
-            r = {util.pconvert(p): v for p, v in r.iteritems()}
+            r = {util.pconvert(p): v for p, v in pycompat.iteritems(r)}
             for path in sorted(r):
                 # ignore malicious paths
                 if not path.startswith(b'fastannotate/') or b'/../' in (
diff --git a/hgext/fastannotate/context.py b/hgext/fastannotate/context.py
--- a/hgext/fastannotate/context.py
+++ b/hgext/fastannotate/context.py
@@ -169,7 +169,7 @@ 
 
     def __init__(self, **opts):
         opts = pycompat.byteskwargs(opts)
-        for k, v in self.defaults.iteritems():
+        for k, v in pycompat.iteritems(self.defaults):
             setattr(self, k, opts.get(k, v))
 
     @util.propertycache
@@ -578,7 +578,7 @@ 
             # find an unresolved line and its linelog rev to annotate
             hsh = None
             try:
-                for (rev, _linenum), idxs in key2idxs.iteritems():
+                for (rev, _linenum), idxs in pycompat.iteritems(key2idxs):
                     if revmap.rev2flag(rev) & revmapmod.sidebranchflag:
                         continue
                     hsh = annotateresult[idxs[0]][0]
@@ -589,7 +589,7 @@ 
                 # the remaining key2idxs are not in main branch, resolving them
                 # using the hard way...
                 revlines = {}
-                for (rev, linenum), idxs in key2idxs.iteritems():
+                for (rev, linenum), idxs in pycompat.iteritems(key2idxs):
                     if rev not in revlines:
                         hsh = annotateresult[idxs[0]][0]
                         if self.ui.debugflag:
diff --git a/hgext/eol.py b/hgext/eol.py
--- a/hgext/eol.py
+++ b/hgext/eol.py
@@ -367,7 +367,7 @@ 
 
     if not repo.local():
         return
-    for name, fn in filters.iteritems():
+    for name, fn in pycompat.iteritems(filters):
         repo.adddatafilter(name, fn)
 
     ui.setconfig(b'patch', b'eol', b'auto', b'eol')
diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -151,7 +151,7 @@ 
     def receiver(orig_paths, revnum, author, date, message, pool):
         paths = {}
         if orig_paths is not None:
-            for k, v in orig_paths.iteritems():
+            for k, v in pycompat.iteritems(orig_paths):
                 paths[k] = changedpath(v)
         pickle.dump((paths, revnum, author, date, message), fp, protocol)
 
@@ -245,7 +245,7 @@ 
         def receiver(orig_paths, revnum, author, date, message, pool):
             paths = {}
             if orig_paths is not None:
-                for k, v in orig_paths.iteritems():
+                for k, v in pycompat.iteritems(orig_paths):
                     paths[k] = changedpath(v)
             self.append((paths, revnum, author, date, message))
 
@@ -591,7 +591,7 @@ 
             )
             files = [
                 n
-                for n, e in entries.iteritems()
+                for n, e in pycompat.iteritems(entries)
                 if e.kind == svn.core.svn_node_file
             ]
             self.removed = set()
@@ -681,7 +681,7 @@ 
                     origpaths = []
                 copies = [
                     (e.copyfrom_path, e.copyfrom_rev, p)
-                    for p, e in origpaths.iteritems()
+                    for p, e in pycompat.iteritems(origpaths)
                     if e.copyfrom_path
                 ]
                 # Apply moves/copies from more specific to general
@@ -712,7 +712,7 @@ 
                 # be represented in mercurial.
                 addeds = dict(
                     (p, e.copyfrom_path)
-                    for p, e in origpaths.iteritems()
+                    for p, e in pycompat.iteritems(origpaths)
                     if e.action == b'A' and e.copyfrom_path
                 )
                 badroots = set()
@@ -1001,7 +1001,7 @@ 
             parents = []
             # check whether this revision is the start of a branch or part
             # of a branch renaming
-            orig_paths = sorted(orig_paths.iteritems())
+            orig_paths = sorted(pycompat.iteritems(orig_paths))
             root_paths = [
                 (p, e) for p, e in orig_paths if self.module.startswith(p)
             ]
@@ -1168,7 +1168,7 @@ 
             path += b'/'
         return (
             (path + p)
-            for p, e in entries.iteritems()
+            for p, e in pycompat.iteritems(entries)
             if e.kind == svn.core.svn_node_file
         )
 
diff --git a/hgext/convert/monotone.py b/hgext/convert/monotone.py
--- a/hgext/convert/monotone.py
+++ b/hgext/convert/monotone.py
@@ -103,7 +103,7 @@ 
         # Prepare the command in automate stdio format
         kwargs = pycompat.byteskwargs(kwargs)
         command = []
-        for k, v in kwargs.iteritems():
+        for k, v in pycompat.iteritems(kwargs):
             command.append(b"%d:%s" % (len(k), k))
             if v:
                 command.append(b"%d:%s" % (len(v), v))
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -34,6 +34,7 @@ 
     merge as mergemod,
     node as nodemod,
     phases,
+    pycompat,
     scmutil,
     util,
 )
@@ -133,7 +134,7 @@ 
 
         if missings:
             self.after()
-            for pbranch, heads in sorted(missings.iteritems()):
+            for pbranch, heads in sorted(pycompat.iteritems(missings)):
                 pbranchpath = os.path.join(self.path, pbranch)
                 prepo = hg.peer(self.ui, {}, pbranchpath)
                 self.ui.note(
@@ -227,7 +228,7 @@ 
             followcopies=False,
         )
 
-        for file, (action, info, msg) in actions.iteritems():
+        for file, (action, info, msg) in pycompat.iteritems(actions):
             if source.targetfilebelongstosource(file):
                 # If the file belongs to the source repo, ignore the p2
                 # since it will be covered by the existing fileset.
@@ -417,7 +418,7 @@ 
         tagparent = tagparent or nodemod.nullid
 
         oldlines = set()
-        for branch, heads in self.repo.branchmap().iteritems():
+        for branch, heads in pycompat.iteritems(self.repo.branchmap()):
             for h in heads:
                 if b'.hgtags' in self.repo[h]:
                     oldlines.update(
@@ -589,7 +590,7 @@ 
         maappend = ma.append
         rappend = r.append
         d = ctx1.manifest().diff(ctx2.manifest())
-        for f, ((node1, flag1), (node2, flag2)) in d.iteritems():
+        for f, ((node1, flag1), (node2, flag2)) in pycompat.iteritems(d):
             if node2 is None:
                 rappend(f)
             else:
@@ -615,7 +616,7 @@ 
         cleanp2 = set()
         if len(parents) == 2:
             d = parents[1].manifest().diff(ctx.manifest(), clean=True)
-            for f, value in d.iteritems():
+            for f, value in pycompat.iteritems(d):
                 if value is None:
                     cleanp2.add(f)
         changes = [(f, rev) for f in files if f not in self.ignored]
diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py
--- a/hgext/convert/filemap.py
+++ b/hgext/convert/filemap.py
@@ -126,7 +126,7 @@ 
         repo belong to the source repo and what parts don't."""
         if self.targetprefixes is None:
             self.targetprefixes = set()
-            for before, after in self.rename.iteritems():
+            for before, after in pycompat.iteritems(self.rename):
                 self.targetprefixes.add(after)
 
         # If "." is a target, then all target files are considered from the
diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py
--- a/hgext/convert/cvsps.py
+++ b/hgext/convert/cvsps.py
@@ -470,7 +470,7 @@ 
 
             # find the branches starting from this revision
             branchpoints = set()
-            for branch, revision in branchmap.iteritems():
+            for branch, revision in pycompat.iteritems(branchmap):
                 revparts = tuple([int(i) for i in revision.split(b'.')])
                 if len(revparts) < 2:  # bad tags
                     continue
diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py
--- a/hgext/convert/cvs.py
+++ b/hgext/convert/cvs.py
@@ -19,6 +19,7 @@ 
 from mercurial import (
     encoding,
     error,
+    pycompat,
     util,
 )
 from mercurial.utils import (
@@ -319,7 +320,7 @@ 
         if full:
             raise error.Abort(_(b"convert from cvs does not support --full"))
         self._parse()
-        return sorted(self.files[rev].iteritems()), {}, set()
+        return sorted(pycompat.iteritems(self.files[rev])), {}, set()
 
     def getcommit(self, rev):
         self._parse()
diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py
--- a/hgext/convert/convcmd.py
+++ b/hgext/convert/convcmd.py
@@ -581,7 +581,7 @@ 
                         # previous one so we don't end up with extra tag heads
                         tagsparents = [
                             e
-                            for e in self.map.iteritems()
+                            for e in pycompat.iteritems(self.map)
                             if e[1] == tagsparent
                         ]
                         if tagsparents:
diff --git a/hgext/convert/common.py b/hgext/convert/common.py
--- a/hgext/convert/common.py
+++ b/hgext/convert/common.py
@@ -411,7 +411,7 @@ 
     def _cmdline(self, cmd, *args, **kwargs):
         kwargs = pycompat.byteskwargs(kwargs)
         cmdline = [self.command, cmd] + list(args)
-        for k, v in kwargs.iteritems():
+        for k, v in pycompat.iteritems(kwargs):
             if len(k) == 1:
                 cmdline.append(b'-' + k)
             else:
diff --git a/hgext/convert/bzr.py b/hgext/convert/bzr.py
--- a/hgext/convert/bzr.py
+++ b/hgext/convert/bzr.py
@@ -12,7 +12,11 @@ 
 import os
 
 from mercurial.i18n import _
-from mercurial import demandimport, error
+from mercurial import (
+    demandimport,
+    error,
+    pycompat,
+)
 from . import common
 
 # these do not work with demandimport, blacklist
@@ -195,7 +199,7 @@ 
             if not branch.supports_tags():
                 return {}
             tagdict = branch.tags.get_tag_dict()
-            for name, rev in tagdict.iteritems():
+            for name, rev in pycompat.iteritems(tagdict):
                 bytetags[self.recode(name)] = rev
         return bytetags
 
diff --git a/hgext/absorb.py b/hgext/absorb.py
--- a/hgext/absorb.py
+++ b/hgext/absorb.py
@@ -726,7 +726,7 @@ 
 
     def apply(self):
         """apply fixups to individual filefixupstates"""
-        for path, state in self.fixupmap.iteritems():
+        for path, state in pycompat.iteritems(self.fixupmap):
             if self.ui.debugflag:
                 self.ui.write(_(b'applying fixups to %s\n') % path)
             state.apply()
@@ -736,7 +736,7 @@ 
         """-> {path: chunkstats}. collect chunkstats from filefixupstates"""
         return dict(
             (path, state.chunkstats)
-            for path, state in self.fixupmap.iteritems()
+            for path, state in pycompat.iteritems(self.fixupmap)
         )
 
     def commit(self):
@@ -755,7 +755,7 @@ 
         chunkstats = self.chunkstats
         if ui.verbose:
             # chunkstats for each file
-            for path, stat in chunkstats.iteritems():
+            for path, stat in pycompat.iteritems(chunkstats):
                 if stat[0]:
                     ui.write(
                         _(b'%s: %d of %d chunk(s) applied\n')
@@ -831,7 +831,7 @@ 
         repo = self.repo
         needupdate = [
             (name, self.replacemap[hsh])
-            for name, hsh in repo._bookmarks.iteritems()
+            for name, hsh in pycompat.iteritems(repo._bookmarks)
             if hsh in self.replacemap
         ]
         changes = []
@@ -890,7 +890,7 @@ 
         # ctx changes more files (not a subset of memworkingcopy)
         if not set(ctx.files()).issubset(set(memworkingcopy)):
             return False
-        for path, content in memworkingcopy.iteritems():
+        for path, content in pycompat.iteritems(memworkingcopy):
             if path not in pctx or path not in ctx:
                 return False
             fctx = ctx[path]
@@ -922,7 +922,7 @@ 
     def _cleanupoldcommits(self):
         replacements = {
             k: ([v] if v is not None else [])
-            for k, v in self.replacemap.iteritems()
+            for k, v in pycompat.iteritems(self.replacemap)
         }
         if replacements:
             scmutil.cleanupnodes(
@@ -968,7 +968,7 @@ 
         if not path or not info:
             continue
         patchmap[path].append(info)
-    for path, patches in patchmap.iteritems():
+    for path, patches in pycompat.iteritems(patchmap):
         if path not in ctx or not patches:
             continue
         patches.sort(reverse=True)