[PATCH 1 of 5] dispatch: make loading extra information from extension extensible

Sean Farley sean at farley.io
Thu Jan 7 14:00:38 CST 2016


Yuya Nishihara <yuya at tcha.org> writes:

> On Tue, 05 Jan 2016 20:48:34 +0900, FUJIWARA Katsunori wrote:
>> # HG changeset patch
>> # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
>> # Date 1451994203 -32400
>> #      Tue Jan 05 20:43:23 2016 +0900
>> # Node ID e526fa5df73b5263d164bd339251481050755720
>> # Parent  b8405d739149cdd6d8d9bd5e3dd2ad8487b1f09a
>> dispatch: make loading extra information from extension extensible
>> 
>> This patch makes loading extra information from extension module at
>> dispatching extensible. This assumes registration of new function like
>> below, for example:
>> 
>>   - revset predicate
>>   - fileset predicate
>>   - template keyword
>>   - template filter
>>   - template function
>>   - internal merge tool
>>   - web command
>> 
>> This patch requires not loader function itself but container module
>> and the name of it, because listing loader function directly up
>> implies loading module of it, even if it isn't used at runtime.
>> 
>> diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
>> --- a/mercurial/dispatch.py
>> +++ b/mercurial/dispatch.py
>> @@ -749,6 +749,24 @@ def _checkshellalias(lui, ui, args, prec
>>      restorecommands()
>>  
>>  _loaded = set()
>> +
>> +def _loadcmdtable(ui, name, cmdtable):
>> +    overrides = [cmd for cmd in cmdtable if cmd in commands.table]
>> +    if overrides:
>> +        ui.warn(_("extension '%s' overrides commands: %s\n")
>> +                % (name, " ".join(overrides)))
>> +    commands.table.update(cmdtable)
>> +
>> +# list of (objname, loadermod, loadername) tuple:
>> +# - objname is the name of an object in extension module, from which
>> +#   extra information is loaded
>> +# - loadermod is the module where loader is placed
>> +# - loadername is the name of the function, which takes (ui, objname,
>> +#   obj) arguments
>> +extraloaders = [
>> +    ('cmdtable', None, None), # this is just a place holder for 'cmdtable'
>
> No special case would be necessary if the commands module had loadcmdtable().
> (or updatecmdtable(), registercmdtable(), ... just bikeshedding ;)
>
>>      # (uisetup and extsetup are handled in extensions.loadall)
>>  
>> +    loadercache = {'cmdtable': _loadcmdtable}
>
> And this cache will no longer be necessary as getattr() should be fast.
>
>>      for name, module in exts:
>> -        cmdtable = getattr(module, 'cmdtable', {})
>> -        overrides = [cmd for cmd in cmdtable if cmd in commands.table]
>> -        if overrides:
>> -            ui.warn(_("extension '%s' overrides commands: %s\n")
>> -                    % (name, " ".join(overrides)))
>> -        commands.table.update(cmdtable)
>> +        for objname, loadermod, loadername in extraloaders:
>> +            if util.safehasattr(module, objname):
>
> Nit: you can use getattr(module, objname, None).

Should we remove util.safehasattr now?


More information about the Mercurial-devel mailing list