diff --git a/mercurial/registrar.py b/mercurial/registrar.py new file mode 100644 --- /dev/null +++ b/mercurial/registrar.py @@ -0,0 +1,87 @@ +# registrar.py - utilities to register function for specific purpose +# +# Copyright FUJIWARA Katsunori 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