Patchwork D3852: namespaces: let namespaces override singlenode() definition

login
register
mail settings
Submitter phabricator
Date June 28, 2018, 5:14 a.m.
Message ID <fba82aaafded5009a85f2a748a8bc4e0@localhost.localdomain>
Download mbox | patch
Permalink /patch/32474/
State Not Applicable
Headers show

Comments

phabricator - June 28, 2018, 5:14 a.m.
martinvonz updated this revision to Diff 9333.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3852?vs=9331&id=9333

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

AFFECTED FILES
  mercurial/namespaces.py

CHANGE DETAILS




To: martinvonz, #hg-reviewers
Cc: mercurial-devel
Yuya Nishihara - June 28, 2018, 12:59 p.m.
Makes sense. One nit.

> +        if not singlenode:
> +            def singlenode(repo, name):
> +                n = self.namemap(repo, name)
> +                if n:
> +                    # return max revision number
> +                    if len(n) > 1:
> +                        cl = repo.changelog
> +                        maxrev = max(cl.rev(node) for node in n)
> +                        return cl.node(maxrev)
> +                    return n[0]
> +                return None
> +        self.singlenode = singlenode

The default implementation has to be defined as an unbound method to avoid
reference cycle: self.singlenode -> singlenode -> self.
phabricator - June 28, 2018, 12:59 p.m.
yuja added a comment.


  Makes sense. One nit.
  
  > +        if not singlenode:
  >  +            def singlenode(repo, name):
  >  +                n = self.namemap(repo, name)
  >  +                if n:
  >  +                    # return max revision number
  >  +                    if len(n) > 1:
  >  +                        cl = repo.changelog
  >  +                        maxrev = max(cl.rev(node) for node in n)
  >  +                        return cl.node(maxrev)
  >  +                    return n[0]
  >  +                return None
  >  +        self.singlenode = singlenode
  
  The default implementation has to be defined as an unbound method to avoid
  reference cycle: self.singlenode -> singlenode -> self.

REPOSITORY
  rHG Mercurial

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

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

Patch

diff --git a/mercurial/namespaces.py b/mercurial/namespaces.py
--- a/mercurial/namespaces.py
+++ b/mercurial/namespaces.py
@@ -95,21 +95,16 @@ 
 
     def singlenode(self, repo, name):
         """
-        Return the 'best' node for the given name. Best means the first node
-        in the first nonempty list returned by a name-to-nodes mapping function
-        in the defined precedence order.
+        Return the 'best' node for the given name. What's best is defined
+        by the namespace's singlenode() function. The first match returned by
+        a namespace in the defined precedence order is used.
 
         Raises a KeyError if there is no such node.
         """
         for ns, v in self._names.iteritems():
-            n = v.namemap(repo, name)
+            n = v.singlenode(repo, name)
             if n:
-                # return max revision number
-                if len(n) > 1:
-                    cl = repo.changelog
-                    maxrev = max(cl.rev(node) for node in n)
-                    return cl.node(maxrev)
-                return n[0]
+                return n
         raise KeyError(_('no such name: %s') % name)
 
 class namespace(object):
@@ -142,7 +137,7 @@ 
 
     def __init__(self, name, templatename=None, logname=None, colorname=None,
                  logfmt=None, listnames=None, namemap=None, nodemap=None,
-                 deprecated=None, builtin=False):
+                 deprecated=None, builtin=False, singlenode=None):
         """create a namespace
 
         name: the namespace to be registered (in plural form)
@@ -158,6 +153,7 @@ 
         nodemap: function that inputs a node, output name(s)
         deprecated: set of names to be masked for ordinary use
         builtin: whether namespace is implemented by core Mercurial
+        singlenode: function that inputs a name, output best node (or None)
         """
         self.name = name
         self.templatename = templatename
@@ -167,6 +163,18 @@ 
         self.listnames = listnames
         self.namemap = namemap
         self.nodemap = nodemap
+        if not singlenode:
+            def singlenode(repo, name):
+                n = self.namemap(repo, name)
+                if n:
+                    # return max revision number
+                    if len(n) > 1:
+                        cl = repo.changelog
+                        maxrev = max(cl.rev(node) for node in n)
+                        return cl.node(maxrev)
+                    return n[0]
+                return None
+        self.singlenode = singlenode
 
         # if logname is not specified, use the template name as backup
         if self.logname is None: