[PATCH 1 of 4] extensions: obtain docs by importing modules instead of parsing them

Cédric Duval cedricduval at free.fr
Fri Jul 31 01:06:33 CDT 2009


# HG changeset patch
# User Cédric Duval <cedricduval at free.fr>
# Date 1248811268 -7200
# Node ID be5a81430dd6903ac1497315cc49e0456d568a12
# Parent  25255ce87bcfb753df078b2f8cabc6bcb5cb96ce
extensions: obtain docs by importing modules instead of parsing them

diff --git a/mercurial/extensions.py b/mercurial/extensions.py
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -118,6 +118,33 @@
     setattr(container, funcname, wrap)
     return origfn
 
+def listexts(path):
+    '''return a set of extensions available from a given path'''
+    exts = set()
+    path = os.path.abspath(path)
+    try: # might not be a filesystem path
+        list = os.listdir(path)
+    except OSError:
+        return exts
+
+    for e in list:
+        if e.endswith('.py') and e != '__init__.py':
+            exts.add(e.rsplit('.', 1)[0])
+        else:
+            f = os.path.join(path, e, '__init__.py')
+            if os.path.exists(f):
+                exts.add(e)
+    return exts
+
+def doc(name):
+    '''return the docstring for a given extension'''
+    try:
+        mod = find(name)
+    except KeyError:
+        mod = __import__('hgext.' + name)
+        mod = getattr(mod, name)
+    return gettext(mod.__doc__) or _('(no help text available)')
+
 def disabled():
     '''find disabled extensions from hgext
     returns a dict of {name: desc}, and the max name length'''
@@ -125,39 +152,13 @@
     import hgext
     extpath = os.path.dirname(os.path.abspath(hgext.__file__))
 
-    try: # might not be a filesystem path
-        files = os.listdir(extpath)
-    except OSError:
-        return None, 0
-
     exts = {}
     maxlength = 0
-    for e in files:
-
-        if e.endswith('.py'):
-            name = e.rsplit('.', 1)[0]
-            path = os.path.join(extpath, e)
-        else:
-            name = e
-            path = os.path.join(extpath, e, '__init__.py')
-            if not os.path.exists(path):
-                continue
-
-        if name in exts or name in _order or name == '__init__':
+    for name in listexts(extpath):
+        if name in _order:
             continue
 
-        try:
-            file = open(path)
-        except IOError:
-            continue
-        else:
-            doc = help.moduledoc(file)
-            file.close()
-
-        if doc: # extracting localized synopsis
-            exts[name] = gettext(doc).splitlines()[0]
-        else:
-            exts[name] = _('(no help text available)')
+        exts[name] = doc(name).splitlines()[0]
 
         if len(name) > maxlength:
             maxlength = len(name)
diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -9,36 +9,6 @@
 import extensions, util
 
 
-def moduledoc(file):
-    '''return the top-level python documentation for the given file
-
-    Loosely inspired by pydoc.source_synopsis(), but rewritten to handle \'''
-    as well as """ and to return the whole text instead of just the synopsis'''
-    result = []
-
-    line = file.readline()
-    while line[:1] == '#' or not line.strip():
-        line = file.readline()
-        if not line: break
-
-    start = line[:3]
-    if start == '"""' or start == "'''":
-        line = line[3:]
-        while line:
-            if line.rstrip().endswith(start):
-                line = line.split(start)[0]
-                if line:
-                    result.append(line)
-                break
-            elif not line:
-                return None # unmatched delimiter
-            result.append(line)
-            line = file.readline()
-    else:
-        return None
-
-    return ''.join(result)
-
 def listexts(header, exts, maxlength):
     '''return a text listing of the given extensions'''
     if not exts:



More information about the Mercurial-devel mailing list