Patchwork [STABLE] help: do not abort topicmatch() because of unimportable extensions

login
register
mail settings
Submitter Yuya Nishihara
Date Oct. 20, 2017, 1:24 p.m.
Message ID <cd3e41ae547b07c03bd0.1508505850@mimosa>
Download mbox | patch
Permalink /patch/25261/
State Accepted
Headers show

Comments

Yuya Nishihara - Oct. 20, 2017, 1:24 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1501942537 -32400
#      Sat Aug 05 23:15:37 2017 +0900
# Branch stable
# Node ID cd3e41ae547b07c03bd05ee0fef23ca27504383b
# Parent  498697fe41f2ff08432743d62ee87f9c22630c81
help: do not abort topicmatch() because of unimportable extensions

This is alternative workaround to D1198, originally spotted by the earlier
version of the releasenotes extension.
Yuya Nishihara - Oct. 20, 2017, 3:19 p.m.
On Fri, 20 Oct 2017 10:07:03 -0500, Kevin Bullock wrote:
> (+junw)
> 
> > On Oct 20, 2017, at 10:06, Kevin Bullock <kbullock+mercurial@ringworld.org> wrote:
> > 
> >> On Oct 20, 2017, at 08:24, Yuya Nishihara <yuya@tcha.org> wrote:
> >> 
> >> # HG changeset patch
> >> # User Yuya Nishihara <yuya@tcha.org>
> >> # Date 1501942537 -32400
> >> #      Sat Aug 05 23:15:37 2017 +0900
> >> # Branch stable
> >> # Node ID cd3e41ae547b07c03bd05ee0fef23ca27504383b
> >> # Parent  498697fe41f2ff08432743d62ee87f9c22630c81
> >> help: do not abort topicmatch() because of unimportable extensions
> >> 
> >> This is alternative workaround to D1198, originally spotted by the earlier
> >> version of the releasenotes extension.
> > 
> > I thought the error was arising from some combination of chg and highlight? I can't trigger the problem here, can you give me some pointers?

It's demandimport or not. With chg where demandimport disabled,
hgext/highlight/highlight.py is imported at early stage and ImportError
would be raised if pygments weren't installed.

% HGRCPATH=/dev/null HGDEMANDIMPORT=disable ./hg help -k foo --traceback
Traceback (most recent call last):
  File "mercurial/scmutil.py", line 154, in callcatch
    return func()
  File "mercurial/dispatch.py", line 303, in _runcatchfunc
    return _dispatch(req)
  File "mercurial/dispatch.py", line 940, in _dispatch
    cmdpats, cmdoptions)
  File "mercurial/dispatch.py", line 701, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "mercurial/dispatch.py", line 948, in _runcommand
    return cmdfunc()
  File "mercurial/dispatch.py", line 937, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
  File "mercurial/util.py", line 1183, in check
    return func(*args, **kwargs)
  File "mercurial/commands.py", line 2663, in help_
    formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
  File "mercurial/help.py", line 655, in formattedhelp
    subtopic=subtopic, unknowncmd=unknowncmd, full=full, **opts)
  File "mercurial/help.py", line 576, in help_
    matches = topicmatch(ui, commands, name or '')
  File "mercurial/help.py", line 161, in topicmatch
    mod = extensions.load(ui, name, '')
  File "mercurial/extensions.py", line 160, in load
    mod = _importext(name, path, bind(_reportimporterror, ui))
  File "mercurial/extensions.py", line 114, in _importext
    mod = _importh(name)
  File "mercurial/extensions.py", line 91, in _importh
    mod = __import__(pycompat.sysstr(name))
ImportError: No module named highlight
abort: No module named highlight!

Patch

diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -158,11 +158,15 @@  def topicmatch(ui, commands, kw):
         extensions.disabled().iteritems()):
         if not docs:
             continue
-        mod = extensions.load(ui, name, '')
         name = name.rpartition('.')[-1]
         if lowercontains(name) or lowercontains(docs):
             # extension docs are already translated
             results['extensions'].append((name, docs.splitlines()[0]))
+        try:
+            mod = extensions.load(ui, name, '')
+        except ImportError:
+            # debug message would be printed in extensions.load()
+            continue
         for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
             if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
                 cmdname = cmd.partition('|')[0].lstrip('^')