[PATCH 1 of 3] registrar: add templatekeyword to mark a function as template keyword (API)
FUJIWARA Katsunori
foozy at lares.dti.ne.jp
Sun Mar 13 09:57:56 EDT 2016
At Sat, 12 Mar 2016 12:48:36 -0800,
Sean Farley wrote:
>
>
> FUJIWARA Katsunori <foozy at lares.dti.ne.jp> writes:
>
> > # HG changeset patch
> > # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
> > # Date 1457813826 -32400
> > # Sun Mar 13 05:17:06 2016 +0900
> > # Node ID dec6fedbede5d40088f18057f49ae5c4ebd634ef
> > # Parent 70c2f8a982766b512e9d7f41f2d93fdb92f5481f
> > registrar: add templatekeyword to mark a function as template keyword (API)
> >
> > _templateregistrarbase is defined as a super class of templatekeyword,
> > for ease of adding template common features between "keyword",
> > "filter" and "function".
> >
> > This patch also adds loadkeyword() to templatekw, because this
> > combination helps to figure out how they cooperate with each other.
> >
> > Listing up loadkeyword() in dispatch.extraloaders causes implicit
> > loading template keyword functions at loading (3rd party) extension.
> >
> > This change requires that "templatekeyword" attribute of (3rd party)
> > extension is registrar.templatekeyword or so.
>
> A few things are a little unclear to me:
>
> - these patches are needed so that template keywords in 3rd party
> extensions aren't implicitly loaded? How is that bad?
Main purpose of this (, previous and subsequent) series is increasing
maintainability of function registration in Mercurial source. For
example, usage of annotation can:
- localize "function definition" and "putting it into table"
- hide internal implementation of optional attributes
(e.g. "safe" of revset, "callstatus" and "callexisting" of fileset)
Loading template keyword function from 3rd party extension implicitly
is a side effect.
> - how will extensions support both 3.7 and 3.8 with your changes?
It might be like as below:
# code for portability >>>>
try:
from mercurial import registrar
if not util.safehasattr(registrar, 'templatekeyword'):
raise ImportError()
templatekeyword = registrar.templatekeyword()
loadkeyword = lambda registrarobj: None # nop
except ImportError:
# registrar.templatekeyword isn't available = loading by old hg
# minimum copy from registrar._funcregistrarbase
class _funcregistrarbase(object):
....
templatekeyword = _funcregistrarbase()
templatekeyword._docformat = ":%s: %s"
# minimum copy from templatekw.loadkeyword
def loadkeyword(registrarobj):
from mercurial import templatekw
for name, func in registrarobj._table.iteritems():
templatekw.keywords[name] = func
# <<<< code for portability
# use templatekeyword to mark function as template keyword
@templatekeywrd('xxxx')
def xxxx(...):
"""Explanation of keyword xxxx
"""
:
:
def extsetup(ui):
# load keyword function, if registrar.templatekeyword not available
loadkeyword(templatekeyword)
I'm planning to write detail of this into WritingExtensions wiki page,
and to provide an utility module as a part of "a skeleton extension"
proposed as issue4677 by Matt.
https://bz.mercurial-scm.org/show_bug.cgi?id=4677
> - how can an extension dynamically create a template keyword with your
> changes?
It can dynamically create template keyword by code path like as below:
dynpredicate = registrar.templatekeyword()
# mark function as template keyword by dynpredicate
dynpredicate("name_of_keyword")(keyword_func)
:
:
# register marked functions as template keyword
templatekw.loadkeyword(ui, 'name_of_extension', dynpredicate)
----------------------------------------------------------------------
[FUJIWARA Katsunori] foozy at lares.dti.ne.jp
More information about the Mercurial-devel
mailing list