mercurial/registrar.py
changeset 27583 37d50250b696
child 27584 fc7c8cac6a4b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/registrar.py	Tue Dec 29 23:58:30 2015 +0900
@@ -0,0 +1,87 @@
+# registrar.py - utilities to register function for specific purpose
+#
+#  Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
+#
+# 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
+
+from . import (
+    util,
+)
+
+class funcregistrar(object):
+    """Base of decorator to register a fuction for specific purpose
+
+    The least derived class can be defined by overriding 'table' and
+    'formatdoc', for example::
+
+        symbols = {}
+        class keyword(funcregistrar):
+            table = symbols
+            formatdoc = ":%s: %s"
+
+        @keyword('bar')
+        def barfunc(*args, **kwargs):
+            '''Explanation of bar keyword ....
+            '''
+            pass
+
+    In this case:
+
+    - 'barfunc' is registered as 'bar' in 'symbols'
+    - online help uses ":bar: Explanation of bar keyword"
+    """
+
+    def __init__(self, decl):
+        """'decl' is a name or more descriptive string of a function
+
+        Specification of 'decl' depends on registration purpose.
+        """
+        self.decl = decl
+
+    table = None
+
+    def __call__(self, func):
+        """Execute actual registration for specified function
+        """
+        name = self.getname()
+
+        if func.__doc__ and not util.safehasattr(func, '_origdoc'):
+            doc = func.__doc__.strip()
+            func._origdoc = doc
+            if callable(self.formatdoc):
+                func.__doc__ = self.formatdoc(doc)
+            else:
+                # convenient shortcut for simple format
+                func.__doc__ = self.formatdoc % (self.decl, doc)
+
+        self.table[name] = func
+        self.extraaction(name, func)
+
+        return func
+
+    def getname(self):
+        """Return the name of the registered function from self.decl
+
+        Derived class should override this, if it allows more
+        descriptive 'decl' string than just a name.
+        """
+        return self.decl
+
+    def formatdoc(self, doc):
+        """Return formatted document of the registered function for help
+
+        'doc' is '__doc__.strip()' of the registered function.
+
+        If this is overridden by non-callable object in derived class,
+        such value is treated as "format string" and used to format
+        document by 'self.formatdoc % (self.decl, doc)' for convenience.
+        """
+        raise NotImplementedError()
+
+    def extraaction(self, name, func):
+        """Execute exra action for registered function, if needed
+        """
+        pass