[PATCH 1 of 3] registrar: add templatekeyword to mark a function as template keyword (API)

Sean Farley sean at farley.io
Sun Mar 13 18:03:02 EDT 2016


FUJIWARA Katsunori <foozy at lares.dti.ne.jp> writes:

> 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)

Thanks for the explanation! I like this series now :-)


More information about the Mercurial-devel mailing list