#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) 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 * #205: When copying files, don't copy full stat info, only
modification times. 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.pycode import ModuleAnalyzer, PycodeError
from sphinx.application import ExtensionError from sphinx.application import ExtensionError
from sphinx.util.compat import Directive from sphinx.util.compat import Directive
from sphinx.util.inspect import isdescriptor, safe_getmembers, safe_getattr
from sphinx.util.docstrings import prepare_docstring from sphinx.util.docstrings import prepare_docstring
@@ -194,25 +195,6 @@ def between(marker, what=None, keepempty=False):
return process 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): class Documenter(object):
""" """
A Documenter knows how to autodocument a single object type. When A Documenter knows how to autodocument a single object type. When
@@ -486,9 +468,9 @@ class Documenter(object):
% (mname, self.fullname)) % (mname, self.fullname))
return False, ret return False, ret
elif self.options.inherited_members: 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 # base classes
return False, inspect.getmembers(self.object) return False, safe_getmembers(self.object)
else: else:
# __dict__ contains only the members directly defined in # __dict__ contains only the members directly defined in
# the class (but get them via getattr anyway, to e.g. get # 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__'): if not hasattr(self.object, '__all__'):
# for implicit module members, check __module__ to avoid # for implicit module members, check __module__ to avoid
# documenting imported objects # documenting imported objects
return True, inspect.getmembers(self.object) return True, safe_getmembers(self.object)
else: else:
memberlist = self.object.__all__ memberlist = self.object.__all__
else: 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