#229: Fix autodoc failures with members that raise errors

on ``getattr()``.
This commit is contained in:
Georg Brandl
2009-08-06 22:06:19 +02:00
parent efa16ae0c7
commit c914884f57
3 changed files with 50 additions and 22 deletions

View File

@@ -1,6 +1,9 @@
Release 0.6.3 (in development)
==============================
* #229: Fix autodoc failures with members that raise errors
on ``getattr()``.
* #205: When copying files, don't copy full stat info, only
modification times.

View File

@@ -25,6 +25,7 @@ from sphinx.util import rpartition, nested_parse_with_titles, force_decode
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.application import ExtensionError
from sphinx.util.compat import Directive
from sphinx.util.inspect import isdescriptor, safe_getmembers, safe_getattr
from sphinx.util.docstrings import prepare_docstring
@@ -194,25 +195,6 @@ def between(marker, what=None, keepempty=False):
return process
def safe_getattr(obj, name, *defargs):
try:
return getattr(obj, name, *defargs)
except Exception:
# this is a catch-all for all the weird things that some modules do
# with attribute access
if defargs:
return defargs[0]
raise AttributeError
def isdescriptor(x):
"""Check if the object is some kind of descriptor."""
for item in '__get__', '__set__', '__delete__':
if hasattr(safe_getattr(x, item, None), '__call__'):
return True
return False
class Documenter(object):
"""
A Documenter knows how to autodocument a single object type. When
@@ -486,9 +468,9 @@ class Documenter(object):
% (mname, self.fullname))
return False, ret
elif self.options.inherited_members:
# getmembers() uses dir() which pulls in members from all
# safe_getmembers() uses dir() which pulls in members from all
# base classes
return False, inspect.getmembers(self.object)
return False, safe_getmembers(self.object)
else:
# __dict__ contains only the members directly defined in
# the class (but get them via getattr anyway, to e.g. get
@@ -728,7 +710,7 @@ class ModuleDocumenter(Documenter):
if not hasattr(self.object, '__all__'):
# for implicit module members, check __module__ to avoid
# documenting imported objects
return True, inspect.getmembers(self.object)
return True, safe_getmembers(self.object)
else:
memberlist = self.object.__all__
else:

43
sphinx/util/inspect.py Normal file
View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
"""
sphinx.util.inspect
~~~~~~~~~~~~~~~~~~~
Helpers for inspecting Python modules.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
def isdescriptor(x):
"""Check if the object is some kind of descriptor."""
for item in '__get__', '__set__', '__delete__':
if hasattr(safe_getattr(x, item, None), '__call__'):
return True
return False
def safe_getattr(obj, name, *defargs):
"""A getattr() that turns all exceptions into AttributeErrors."""
try:
return getattr(obj, name, *defargs)
except Exception:
# this is a catch-all for all the weird things that some modules do
# with attribute access
if defargs:
return defargs[0]
raise AttributeError(name)
def safe_getmembers(object, predicate=None):
"""A version of inspect.getmembers() that uses safe_getattr()."""
results = []
for key in dir(object):
try:
value = safe_getattr(object, key, None)
except AttributeError:
continue
if not predicate or predicate(value):
results.append((key, value))
results.sort()
return results