#347: use autodoc documenter detection in autosummary.

This commit is contained in:
Georg Brandl 2011-01-15 15:10:30 +01:00
parent c0aad06b96
commit e7fa3c6f45
3 changed files with 26 additions and 27 deletions

View File

@ -1,6 +1,9 @@
Release 1.0.7 (in development) 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``. * #599: Import PIL as ``from PIL import Image``.
* #558: Fix longtables with captions in LaTeX output. * #558: Fix longtables with captions in LaTeX output.

View File

@ -134,27 +134,19 @@ except AttributeError:
return False return False
isgetsetdescriptor = ismemberdescriptor isgetsetdescriptor = ismemberdescriptor
def get_documenter(obj): def get_documenter(obj, parent):
""" """
Get an autodoc.Documenter class suitable for documenting the given object 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): classes = [cls for cls in AutoDirective._registry.values()
if issubclass(obj, Exception): if cls.can_document_member(obj, '', False, parent)]
return autodoc.ExceptionDocumenter if classes:
return autodoc.ClassDocumenter classes.sort(key=lambda cls: cls.priority)
elif inspect.ismodule(obj): return classes[-1]
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
else: else:
return autodoc.DataDocumenter return DataDocumenter
# -- .. autosummary:: ---------------------------------------------------------- # -- .. autosummary:: ----------------------------------------------------------
@ -240,7 +232,7 @@ class Autosummary(Directive):
display_name = name.split('.')[-1] display_name = name.split('.')[-1]
try: try:
obj, real_name = import_by_name(name, prefixes=prefixes) real_name, obj, parent = import_by_name(name, prefixes=prefixes)
except ImportError: except ImportError:
self.warn('failed to import %s' % name) self.warn('failed to import %s' % name)
items.append((name, '', '', name)) items.append((name, '', '', name))
@ -248,7 +240,7 @@ class Autosummary(Directive):
# NB. using real_name here is important, since Documenters # NB. using real_name here is important, since Documenters
# handle module prefixes slightly differently # 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(): if not documenter.parse_name():
self.warn('failed to parse name %s' % real_name) self.warn('failed to parse name %s' % real_name)
items.append((display_name, '', '', real_name)) items.append((display_name, '', '', real_name))
@ -388,7 +380,8 @@ def import_by_name(name, prefixes=[None]):
prefixed_name = '.'.join([prefix, name]) prefixed_name = '.'.join([prefix, name])
else: else:
prefixed_name = name 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: except ImportError:
tried.append(prefixed_name) tried.append(prefixed_name)
raise ImportError('no module named %s' % ' or '.join(tried)) raise ImportError('no module named %s' % ' or '.join(tried))
@ -403,7 +396,8 @@ def _import_by_name(name):
if modname: if modname:
try: try:
__import__(modname) __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): except (ImportError, IndexError, AttributeError):
pass pass
@ -421,12 +415,14 @@ def _import_by_name(name):
break break
if last_j < len(name_parts): if last_j < len(name_parts):
parent = None
obj = sys.modules[modname] obj = sys.modules[modname]
for obj_name in name_parts[last_j:]: for obj_name in name_parts[last_j:]:
parent = obj
obj = getattr(obj, obj_name) obj = getattr(obj, obj_name)
return obj return obj, parent
else: else:
return sys.modules[modname] return sys.modules[modname], None
except (ValueError, ImportError, AttributeError, KeyError), e: except (ValueError, ImportError, AttributeError, KeyError), e:
raise ImportError(*e.args) raise ImportError(*e.args)
@ -449,7 +445,7 @@ def autolink_role(typ, rawtext, etext, lineno, inliner,
prefixes = [None] prefixes = [None]
#prefixes.insert(0, inliner.document.settings.env.currmodule) #prefixes.insert(0, inliner.document.settings.env.currmodule)
try: try:
obj, name = import_by_name(pnode['reftarget'], prefixes) name, obj, parent = import_by_name(pnode['reftarget'], prefixes)
except ImportError: except ImportError:
content = pnode[0] content = pnode[0]
r[0][0] = nodes.emphasis(rawtext, content[0].astext(), r[0][0] = nodes.emphasis(rawtext, content[0].astext(),

View File

@ -107,7 +107,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
ensuredir(path) ensuredir(path)
try: try:
obj, name = import_by_name(name) name, obj, parent = import_by_name(name)
except ImportError, e: except ImportError, e:
warn('[autosummary] failed to import %r: %s' % (name, e)) warn('[autosummary] failed to import %r: %s' % (name, e))
continue continue
@ -123,7 +123,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
f = open(fn, 'w') f = open(fn, 'w')
try: try:
doc = get_documenter(obj) doc = get_documenter(obj, parent)
if template_name is not None: if template_name is not None:
template = template_env.get_template(template_name) 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=[]): def get_members(obj, typ, include_public=[]):
items = [ items = [
name for name in dir(obj) 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 public = [x for x in items
if x in include_public or not x.startswith('_')] 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`. See `find_autosummary_in_lines`.
""" """
try: try:
obj, real_name = import_by_name(name) real_name, obj, parent = import_by_name(name)
lines = pydoc.getdoc(obj).splitlines() lines = pydoc.getdoc(obj).splitlines()
return find_autosummary_in_lines(lines, module=name, filename=filename) return find_autosummary_in_lines(lines, module=name, filename=filename)
except AttributeError: except AttributeError: