[PATCH 2 of 2 RFC] use util.defaultdict instead of dict + setdefault (+get)

Nicolas Dumazet nicdumz at gmail.com
Sat Aug 22 16:53:41 CDT 2009


# HG changeset patch
# User Nicolas Dumazet <nicdumz.commits at gmail.com>
# Date 1250869246 -7200
# Node ID e58651fb4208380627b9d5db243645503645e332
# Parent  d592614e7f2e9fe3ce844e4c5d3d591a61c1832e
use util.defaultdict instead of dict + setdefault (+get)

diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py
--- a/hgext/convert/convcmd.py
+++ b/hgext/convert/convcmd.py
@@ -126,7 +126,7 @@
             """
             visit = parents.keys()
             seen = set()
-            children = {}
+            children = util.defaultdict(list)
             roots = []
 
             while visit:
@@ -136,13 +136,12 @@
                 seen.add(n)
                 # Ensure that nodes without parents are present in the
                 # 'children' mapping.
-                children.setdefault(n, [])
                 hasparent = False
                 for p in parents[n]:
                     if not p in self.map:
                         visit.append(p)
                         hasparent = True
-                    children.setdefault(p, []).append(n)
+                    children[p].append(n)
                 if not hasparent:
                     roots.append(n)
 
@@ -208,7 +207,7 @@
             s.append(n)
 
             # Update dependents list
-            for c in children.get(n, []):
+            for c in children[n]:
                 if c not in pendings:
                     pendings[c] = [p for p in parents[c] if p not in self.map]
                 try:
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -96,12 +96,12 @@
 
         # pbranches may bring revisions from other branches (merge parents)
         # Make sure we have them, or pull them.
-        missings = {}
+        missings = util.defaultdict(list)
         for b in pbranches:
             try:
                 self.repo.lookup(b[0])
             except:
-                missings.setdefault(b[1], []).append(b[0])
+                missings[b[1]].append(b[0])
 
         if missings:
             self.after()
diff --git a/hgext/gpg.py b/hgext/gpg.py
--- a/hgext/gpg.py
+++ b/hgext/gpg.py
@@ -136,7 +136,7 @@
 def sigs(ui, repo):
     """list signed changesets"""
     mygpg = newgpg(ui)
-    revs = {}
+    revs = util.defaultdict(list)
 
     for data, context in sigwalk(repo):
         node, version, sig = data
@@ -150,7 +150,6 @@
         keys = getkeys(ui, repo, mygpg, data, context)
         if not keys:
             continue
-        revs.setdefault(r, [])
         revs[r].extend(keys)
     for rev in sorted(revs, reverse=True):
         for k in revs[rev]:
diff --git a/hgext/inotify/server.py b/hgext/inotify/server.py
--- a/hgext/inotify/server.py
+++ b/hgext/inotify/server.py
@@ -173,9 +173,9 @@
                     continue
                 raise
             if events:
-                by_fd = {}
+                by_fd = util.defaultdict(list)
                 for fd, event in events:
-                    by_fd.setdefault(fd, []).append(event)
+                    by_fd[fd].append(event)
 
                 for fd, events in by_fd.iteritems():
                     cls.instances[fd].handle_pollevents(events)
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -1239,20 +1239,20 @@
 
                 try:
                     if self.diffopts().git:
-                        copies = {}
+                        copies = util.defaultdict(list)
                         for dst in a:
                             src = repo.dirstate.copied(dst)
                             # during qfold, the source file for copies may
                             # be removed. Treat this as a simple add.
                             if src is not None and src in repo.dirstate:
-                                copies.setdefault(src, []).append(dst)
+                                copies[src].append(dst)
                             repo.dirstate.add(dst)
                         # remember the copies between patchparent and tip
                         for dst in aaa:
                             f = repo.file(dst)
                             src = f.renamed(man[dst])
                             if src:
-                                copies.setdefault(src[0], []).extend(copies.get(dst, []))
+                                copies[src[0]].extend(copies[dst])
                                 if dst in a:
                                     copies[src[0]].append(dst)
                             # we can't copy a file created by the patch itself
@@ -2338,13 +2338,12 @@
                             'from %d to %d\n') %
                           (len(old_guarded), len(guarded)))
     elif opts['series']:
-        guards = {}
+        guards = util.defaultdict(int)
         noguards = 0
         for gs in q.series_guards:
             if not gs:
                 noguards += 1
             for g in gs:
-                guards.setdefault(g, 0)
                 guards[g] += 1
         if ui.verbose:
             guards['NONE'] = noguards
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1055,7 +1055,7 @@
     revs = revrange(repo, opts['rev'] or [defrange])
     wanted = set()
     slowpath = m.anypats() or (m.files() and opts.get('removed'))
-    fncache = {}
+    fncache = util.defaultdict(list)
 
     if not slowpath and not m.files():
         # No files, no patterns.  Display all revs.
@@ -1104,7 +1104,6 @@
                 if rev <= maxrev:
                     if rev < minrev:
                         break
-                    fncache.setdefault(rev, [])
                     fncache[rev].append(file_)
                     wanted.add(rev)
                     if follow and copied:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1236,10 +1236,9 @@
         def __eq__(self, other):
             return self.line == other.line
 
-    matches = {}
-    copies = {}
+    matches = util.defaultdict(lambda: util.defaultdict(list))
+    copies = util.defaultdict(dict)
     def grepbody(fn, rev, body):
-        matches[rev].setdefault(fn, [])
         m = matches[rev][fn]
         for lnum, cstart, cend, line in matchlines(body):
             s = linestate(line, lnum, cstart, cend)
@@ -1290,7 +1289,7 @@
         return found
 
     skip = {}
-    revfiles = {}
+    revfiles = util.defaultdict(list)
     get = util.cachefunc(lambda r: repo[r])
     changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
     found = False
@@ -1303,9 +1302,7 @@
             ctx = get(rev)
             pctx = ctx.parents()[0]
             parent = pctx.rev()
-            matches.setdefault(rev, {})
-            matches.setdefault(parent, {})
-            files = revfiles.setdefault(rev, [])
+            files = revfiles[rev]
             for fn in fns:
                 flog = getfile(fn)
                 try:
@@ -1316,7 +1313,7 @@
                 copied = flog.renamed(fnode)
                 copy = follow and copied and copied[0]
                 if copy:
-                    copies.setdefault(rev, {})[fn] = copy
+                    copies[rev][fn] = copy
                 if fn in skip:
                     if copy:
                         skip[copy] = True
@@ -1335,14 +1332,14 @@
                         pass
         elif st == 'iter':
             parent = get(rev).parents()[0].rev()
-            for fn in sorted(revfiles.get(rev, [])):
+            for fn in sorted(revfiles[rev]):
                 states = matches[rev][fn]
-                copy = copies.get(rev, {}).get(fn)
+                copy = copies[rev].get(fn)
                 if fn in skip:
                     if copy:
                         skip[copy] = True
                     continue
-                pstates = matches.get(parent, {}).get(copy or fn, [])
+                pstates = matches[parent][copy or fn]
                 if pstates or states:
                     r = display(fn, rev, pstates, states)
                     found = found or r
diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -124,7 +124,7 @@
     ctx = util.lrucachefunc(makectx)
     copy = {}
     fullcopy = {}
-    diverge = {}
+    diverge = util.defaultdict(list)
 
     def checkcopies(f, m1, m2):
         '''check possible copies of f from m1 to m2'''
@@ -142,7 +142,7 @@
                         if c1 != ca or c2 != ca: # merge needed?
                             copy[f] = of
             elif of in ma:
-                diverge.setdefault(of, []).append(f)
+                diverge[of].append(f)
 
     repo.ui.debug(_("  searching for copies back to rev %d\n") % limit)
 
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -305,10 +305,10 @@
     def nodetags(self, node):
         '''return the tags associated with a node'''
         if not self.nodetagscache:
-            self.nodetagscache = {}
+            self.nodetagscache = util.defaultdict(list)
             for t, n in self.tags().iteritems():
-                self.nodetagscache.setdefault(n, []).append(t)
-        return self.nodetagscache.get(node, [])
+                self.nodetagscache[n].append(t)
+        return self.nodetagscache[node]
 
     def _branchtags(self, partial, lrev):
         # TODO: rename this function?
@@ -366,13 +366,13 @@
 
 
     def _readbranchcache(self):
-        partial = {}
+        partial = util.defaultdict(list)
         try:
             f = self.opener("branchheads.cache")
             lines = f.read().split('\n')
             f.close()
         except (IOError, OSError):
-            return {}, nullid, nullrev
+            return util.defaultdict(list), nullid, nullrev
 
         try:
             last, lrev = lines.pop(0).split(" ", 1)
@@ -383,13 +383,13 @@
             for l in lines:
                 if not l: continue
                 node, label = l.split(" ", 1)
-                partial.setdefault(label.strip(), []).append(bin(node))
+                partial[label.strip()].append(bin(node))
         except KeyboardInterrupt:
             raise
         except Exception, inst:
             if self.ui.debugflag:
                 self.ui.warn(str(inst), '\n')
-            partial, last, lrev = {}, nullid, nullrev
+            partial, last, lrev = util.defaultdict(list), nullid, nullrev
         return partial, last, lrev
 
     def _writebranchcache(self, branches, tip, tiprev):
@@ -405,15 +405,15 @@
 
     def _updatebranchcache(self, partial, start, end):
         # collect new branch entries
-        newbranches = {}
+        newbranches = util.defaultdict(list)
         for r in xrange(start, end):
             c = self[r]
-            newbranches.setdefault(c.branch(), []).append(c.node())
+            newbranches[c.branch()].append(c.node())
         # if older branchheads are reachable from new ones, they aren't
         # really branchheads. Note checking parents is insufficient:
         # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
         for branch, newnodes in newbranches.iteritems():
-            bheads = partial.setdefault(branch, [])
+            bheads = partial[branch]
             bheads.extend(newnodes)
             if len(bheads) < 2:
                 continue
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -338,9 +338,9 @@
         return cand
 
     def hashlines(self):
-        self.hash = {}
+        self.hash = util.defaultdict(list)
         for x, s in enumerate(self.lines):
-            self.hash.setdefault(s, []).append(x)
+            self.hash[s].append(x)
 
     def write_rej(self):
         # our rejects are a little different from patch(1).  This always
diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -136,11 +136,10 @@
 
     def readauthtoken(self, uri):
         # Read configuration
-        config = dict()
+        config = util.defaultdict(dict)
         for key, val in self.ui.configitems('auth'):
             group, setting = key.split('.', 1)
-            gdict = config.setdefault(group, dict())
-            gdict[setting] = val
+            config[group][setting] = val
 
         # Find the best match
         scheme, hostpath = uri.split('://', 1)
diff --git a/mercurial/verify.py b/mercurial/verify.py
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -17,9 +17,9 @@
         lock.release()
 
 def _verify(repo):
-    mflinkrevs = {}
-    filelinkrevs = {}
-    filenodes = {}
+    mflinkrevs = util.defaultdict(list)
+    filelinkrevs = util.defaultdict(list)
+    filenodes = util.defaultdict(dict)
     revisions = 0
     badrevs = set()
     errors = [0]
@@ -114,9 +114,9 @@
 
         try:
             changes = cl.read(n)
-            mflinkrevs.setdefault(changes[0], []).append(i)
+            mflinkrevs[changes[0]].append(i)
             for f in changes[3]:
-                filelinkrevs.setdefault(f, []).append(i)
+                filelinkrevs[f].append(i)
         except Exception, inst:
             exc(i, _("unpacking changeset %s") % short(n), inst)
 
@@ -136,7 +136,7 @@
                 if not f:
                     err(lr, _("file without name in manifest"))
                 elif f != "/dev/null":
-                    fns = filenodes.setdefault(f, {})
+                    fns = filenodes[f]
                     if fn not in fns:
                         fns[fn] = i
         except Exception, inst:


More information about the Mercurial-devel mailing list