From e7fa3c6f45f9917d0a3ded691ef01e1da36ce20b Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 15 Jan 2011 15:10:30 +0100 Subject: [PATCH] #347: use autodoc documenter detection in autosummary. --- CHANGES | 3 +++ sphinx/ext/autosummary/__init__.py | 42 ++++++++++++++---------------- sphinx/ext/autosummary/generate.py | 8 +++--- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index 7b83ac5a3..e91a032e0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ Release 1.0.7 (in development) ============================== +* #347: Fix wrong generation of directives of static methods in + autosummary. + * #599: Import PIL as ``from PIL import Image``. * #558: Fix longtables with captions in LaTeX output. diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index f75307e01..dace837fe 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -134,27 +134,19 @@ except AttributeError: return False isgetsetdescriptor = ismemberdescriptor -def get_documenter(obj): +def get_documenter(obj, parent): """ Get an autodoc.Documenter class suitable for documenting the given object """ - import sphinx.ext.autodoc as autodoc + from sphinx.ext.autodoc import AutoDirective, DataDocumenter - if inspect.isclass(obj): - if issubclass(obj, Exception): - return autodoc.ExceptionDocumenter - return autodoc.ClassDocumenter - elif inspect.ismodule(obj): - return autodoc.ModuleDocumenter - elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): - return autodoc.MethodDocumenter - elif (ismemberdescriptor(obj) or isgetsetdescriptor(obj) - or inspect.isdatadescriptor(obj)): - return autodoc.AttributeDocumenter - elif inspect.isroutine(obj): - return autodoc.FunctionDocumenter + classes = [cls for cls in AutoDirective._registry.values() + if cls.can_document_member(obj, '', False, parent)] + if classes: + classes.sort(key=lambda cls: cls.priority) + return classes[-1] else: - return autodoc.DataDocumenter + return DataDocumenter # -- .. autosummary:: ---------------------------------------------------------- @@ -240,7 +232,7 @@ class Autosummary(Directive): display_name = name.split('.')[-1] try: - obj, real_name = import_by_name(name, prefixes=prefixes) + real_name, obj, parent = import_by_name(name, prefixes=prefixes) except ImportError: self.warn('failed to import %s' % name) items.append((name, '', '', name)) @@ -248,7 +240,7 @@ class Autosummary(Directive): # NB. using real_name here is important, since Documenters # handle module prefixes slightly differently - documenter = get_documenter(obj)(self, real_name) + documenter = get_documenter(obj, parent)(self, real_name) if not documenter.parse_name(): self.warn('failed to parse name %s' % real_name) items.append((display_name, '', '', real_name)) @@ -388,7 +380,8 @@ def import_by_name(name, prefixes=[None]): prefixed_name = '.'.join([prefix, name]) else: prefixed_name = name - return _import_by_name(prefixed_name), prefixed_name + obj, parent = _import_by_name(prefixed_name) + return prefixed_name, obj, parent except ImportError: tried.append(prefixed_name) raise ImportError('no module named %s' % ' or '.join(tried)) @@ -403,7 +396,8 @@ def _import_by_name(name): if modname: try: __import__(modname) - return getattr(sys.modules[modname], name_parts[-1]) + mod = sys.modules[modname] + return getattr(mod, name_parts[-1]), mod except (ImportError, IndexError, AttributeError): pass @@ -421,12 +415,14 @@ def _import_by_name(name): break if last_j < len(name_parts): + parent = None obj = sys.modules[modname] for obj_name in name_parts[last_j:]: + parent = obj obj = getattr(obj, obj_name) - return obj + return obj, parent else: - return sys.modules[modname] + return sys.modules[modname], None except (ValueError, ImportError, AttributeError, KeyError), e: raise ImportError(*e.args) @@ -449,7 +445,7 @@ def autolink_role(typ, rawtext, etext, lineno, inliner, prefixes = [None] #prefixes.insert(0, inliner.document.settings.env.currmodule) try: - obj, name = import_by_name(pnode['reftarget'], prefixes) + name, obj, parent = import_by_name(pnode['reftarget'], prefixes) except ImportError: content = pnode[0] r[0][0] = nodes.emphasis(rawtext, content[0].astext(), diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index f8230216c..b5ff3f4ca 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -107,7 +107,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', ensuredir(path) try: - obj, name = import_by_name(name) + name, obj, parent = import_by_name(name) except ImportError, e: warn('[autosummary] failed to import %r: %s' % (name, e)) continue @@ -123,7 +123,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', f = open(fn, 'w') try: - doc = get_documenter(obj) + doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) @@ -137,7 +137,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', def get_members(obj, typ, include_public=[]): items = [ name for name in dir(obj) - if get_documenter(getattr(obj, name)).objtype == typ + if get_documenter(getattr(obj, name), obj).objtype == typ ] public = [x for x in items if x in include_public or not x.startswith('_')] @@ -211,7 +211,7 @@ def find_autosummary_in_docstring(name, module=None, filename=None): See `find_autosummary_in_lines`. """ try: - obj, real_name = import_by_name(name) + real_name, obj, parent = import_by_name(name) lines = pydoc.getdoc(obj).splitlines() return find_autosummary_in_lines(lines, module=name, filename=filename) except AttributeError: