D7013: py3: define and use pycompat.itervalues()

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Mon Oct 7 20:08:14 UTC 2019


indygreg created this revision.
Herald added a reviewer: martinvonz.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  .itervalues() only exists on Python 2. Python 3's equivalent is
  .values(). But we don't want to blindly use .values() everywhere
  because on Python 2, it will create a list, which will have performance
  implications.
  
  This commit introduces pycompat.itervalues() which will call the appropriate
  method on the passed object. We update all callers of obj.itervalues()
  to pycompat.itervalues(obj) instead.
  
  With this commit, the only source tranforming remaining is for
  iteritems(). Victory is near...

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  contrib/synthrepo.py
  hgext/journal.py
  hgext/rebase.py
  hgext/remotefilelog/connectionpool.py
  hgext/remotefilelog/debugcommands.py
  hgext/remotefilelog/repack.py
  hgext/transplant.py
  mercurial/__init__.py
  mercurial/branchmap.py
  mercurial/exchangev2.py
  mercurial/localrepo.py
  mercurial/merge.py
  mercurial/patch.py
  mercurial/pycompat.py
  mercurial/statprof.py
  mercurial/ui.py
  tests/test-pathencode.py

CHANGE DETAILS

diff --git a/tests/test-pathencode.py b/tests/test-pathencode.py
--- a/tests/test-pathencode.py
+++ b/tests/test-pathencode.py
@@ -67,7 +67,7 @@
             counts[c] += 1
     for c in '\r/\n':
         counts.pop(c, None)
-    t = sum(counts.itervalues()) / 100.0
+    t = sum(pycompat.itervalues(counts)) / 100.0
     fp.write('probtable = (')
     for i, (k, v) in enumerate(
         sorted(counts.items(), key=lambda x: x[1], reverse=True)
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -1966,7 +1966,7 @@
         if not self._loggers:
             return
         activeloggers = [
-            l for l in self._loggers.itervalues() if l.tracked(event)
+            l for l in pycompat.itervalues(self._loggers) if l.tracked(event)
         ]
         if not activeloggers:
             return
diff --git a/mercurial/statprof.py b/mercurial/statprof.py
--- a/mercurial/statprof.py
+++ b/mercurial/statprof.py
@@ -475,7 +475,7 @@
                 if i == 0:
                     sitestat.addself()
 
-        return [s for s in stats.itervalues()]
+        return [s for s in pycompat.itervalues(stats)]
 
 
 class DisplayFormats:
@@ -744,7 +744,7 @@
         site = node.site
         visiblechildren = [
             c
-            for c in node.children.itervalues()
+            for c in pycompat.itervalues(node.children)
             if c.count >= (limit * root.count)
         ]
         if site:
@@ -752,7 +752,7 @@
             filename = b''
             function = b''
             if len(node.children) > 0:
-                childsite = list(node.children.itervalues())[0].site
+                childsite = list(pycompat.itervalues(node.children))[0].site
                 filename = (childsite.filename() + b':').ljust(15)
                 function = childsite.function
 
@@ -777,7 +777,7 @@
             )
 
             finalstring = liststring + codestring
-            childrensamples = sum([c.count for c in node.children.itervalues()])
+            childrensamples = sum([c.count for c in pycompat.itervalues(node.children)])
             # Make frames that performed more than 10% of the operation red
             if node.count - childrensamples > (0.1 * root.count):
                 finalstring = b'\033[91m' + finalstring + b'\033[0m'
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
+    itervalues = lambda x: x.values()
 
 else:
     import cStringIO
@@ -416,6 +417,7 @@
     ziplist = zip
     rawinput = raw_input
     getargspec = inspect.getargspec
+    itervalues = lambda x: x.itervalues()
 
 isjython = sysplatform.startswith(b'java')
 
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -1326,7 +1326,7 @@
                 fixoffset += chunk.removed - chunk.added
     return (
         sum(
-            [h for h in applied.itervalues() if h[0].special() or len(h) > 1],
+            [h for h in pycompat.itervalues(applied) if h[0].special() or len(h) > 1],
             [],
         ),
         {},
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -702,7 +702,7 @@
         """return counts for updated, merged and removed files in this
         session"""
         updated, merged, removed = 0, 0, 0
-        for r, action in self._results.itervalues():
+        for r, action in pycompat.itervalues(self._results):
             if r is None:
                 updated += 1
             elif r == 0:
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1763,7 +1763,7 @@
             nodetagscache = {}
             for t, n in self._tagscache.tags.iteritems():
                 nodetagscache.setdefault(n, []).append(t)
-            for tags in nodetagscache.itervalues():
+            for tags in pycompat.itervalues(nodetagscache):
                 tags.sort()
             self._tagscache.nodetagscache = nodetagscache
         return self._tagscache.nodetagscache.get(node, [])
diff --git a/mercurial/exchangev2.py b/mercurial/exchangev2.py
--- a/mercurial/exchangev2.py
+++ b/mercurial/exchangev2.py
@@ -607,7 +607,7 @@
     progress = repo.ui.makeprogress(
         _(b'files'),
         unit=_(b'chunks'),
-        total=sum(len(v) for v in fnodes.itervalues()),
+        total=sum(len(v) for v in pycompat.itervalues(fnodes)),
     )
 
     # TODO make batch size configurable
@@ -706,7 +706,7 @@
     progress = repo.ui.makeprogress(
         _(b'files'),
         unit=_(b'chunks'),
-        total=sum(len(v) for v in fnodes.itervalues()),
+        total=sum(len(v) for v in pycompat.itervalues(fnodes)),
     )
 
     commandmeta = remote.apidescriptor[b'commands'][b'filesdata']
diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -91,7 +91,7 @@
         clbranchinfo = cl.branchinfo
         rbheads = []
         closed = []
-        for bheads in remotebranchmap.itervalues():
+        for bheads in pycompat.itervalues(remotebranchmap):
             rbheads += bheads
             for h in bheads:
                 r = clrev(h)
@@ -350,7 +350,7 @@
     def iterheads(self):
         """ returns all the heads """
         self._verifyall()
-        return self._entries.itervalues()
+        return pycompat.itervalues(self._entries)
 
     def copy(self):
         """return an deep copy of the branchcache object"""
diff --git a/mercurial/__init__.py b/mercurial/__init__.py
--- a/mercurial/__init__.py
+++ b/mercurial/__init__.py
@@ -117,7 +117,7 @@
 
                 # It changes iteritems/values to items/values as they are not
                 # present in Python 3 world.
-                if fn in ('iteritems', 'itervalues') and not (
+                if fn == 'iteritems' and not (
                     tokens[i - 1].type == token.NAME
                     and tokens[i - 1].string == 'def'
                 ):
@@ -131,7 +131,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\x14'
+    BYTECODEHEADER = b'HG\x00\x15'
 
     class hgloader(importlib.machinery.SourceFileLoader):
         """Custom module loader that transforms source code.
diff --git a/hgext/transplant.py b/hgext/transplant.py
--- a/hgext/transplant.py
+++ b/hgext/transplant.py
@@ -100,7 +100,7 @@
             if not os.path.isdir(self.path):
                 os.mkdir(self.path)
             fp = self.opener(self.transplantfile, b'w')
-            for list in self.transplants.itervalues():
+            for list in pycompat.itervalues(self.transplants):
                 for t in list:
                     l, r = map(nodemod.hex, (t.lnode, t.rnode))
                     fp.write(l + b':' + r + b'\n')
diff --git a/hgext/remotefilelog/repack.py b/hgext/remotefilelog/repack.py
--- a/hgext/remotefilelog/repack.py
+++ b/hgext/remotefilelog/repack.py
@@ -598,7 +598,7 @@
         maxchainlen = ui.configint(b'packs', b'maxchainlen', 1000)
 
         byfile = {}
-        for entry in ledger.entries.itervalues():
+        for entry in pycompat.itervalues(ledger.entries):
             if entry.datasource:
                 byfile.setdefault(entry.filename, {})[entry.node] = entry
 
@@ -753,7 +753,7 @@
         ui = self.repo.ui
 
         byfile = {}
-        for entry in ledger.entries.itervalues():
+        for entry in pycompat.itervalues(ledger.entries):
             if entry.historysource:
                 byfile.setdefault(entry.filename, {})[entry.node] = entry
 
diff --git a/hgext/remotefilelog/debugcommands.py b/hgext/remotefilelog/debugcommands.py
--- a/hgext/remotefilelog/debugcommands.py
+++ b/hgext/remotefilelog/debugcommands.py
@@ -207,7 +207,7 @@
                 continue
             filepath = os.path.join(root, file)
             size, firstnode, mapping = parsefileblob(filepath, decompress)
-            for p1, p2, linknode, copyfrom in mapping.itervalues():
+            for p1, p2, linknode, copyfrom in pycompat.itervalues(mapping):
                 if linknode == nullid:
                     actualpath = os.path.relpath(root, path)
                     key = fileserverclient.getcachekey(
diff --git a/hgext/remotefilelog/connectionpool.py b/hgext/remotefilelog/connectionpool.py
--- a/hgext/remotefilelog/connectionpool.py
+++ b/hgext/remotefilelog/connectionpool.py
@@ -10,6 +10,7 @@
 from mercurial import (
     extensions,
     hg,
+    pycompat,
     sshpeer,
     util,
 )
@@ -59,7 +60,7 @@
         return conn
 
     def close(self):
-        for pathpool in self._pool.itervalues():
+        for pathpool in pycompat.itervalues(self._pool):
             for conn in pathpool:
                 conn.close()
             del pathpool[:]
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -2288,7 +2288,7 @@
         msg = _(b'rebase: (use "hg rebase --abort" to clear broken state)\n')
         ui.write(msg)
         return
-    numrebased = len([i for i in state.itervalues() if i >= 0])
+    numrebased = len([i for i in pycompat.itervalues(state) if i >= 0])
     # i18n: column positioning for "hg summary"
     ui.write(
         _(b'rebase: %s, %s (rebase --continue)\n')
diff --git a/hgext/journal.py b/hgext/journal.py
--- a/hgext/journal.py
+++ b/hgext/journal.py
@@ -164,7 +164,7 @@
             pass
 
     while iterable_map:
-        value, key, it = order(iterable_map.itervalues())
+        value, key, it = order(pycompat.itervalues(iterable_map))
         yield value
         try:
             iterable_map[key][0] = next(it)
diff --git a/contrib/synthrepo.py b/contrib/synthrepo.py
--- a/contrib/synthrepo.py
+++ b/contrib/synthrepo.py
@@ -213,7 +213,7 @@
             for filename, mar, lineadd, lineremove, isbin in parsegitdiff(diff):
                 if isbin:
                     continue
-                added = sum(lineadd.itervalues(), 0)
+                added = sum(pycompat.itervalues(lineadd), 0)
                 if mar == 'm':
                     if added and lineremove:
                         lineschanged[



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


More information about the Mercurial-devel mailing list