mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
#229: Fix autodoc failures with members that raise errors
on ``getattr()``.
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -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.
|
||||
|
||||
|
||||
@@ -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
43
sphinx/util/inspect.py
Normal 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
|
||||
Reference in New Issue
Block a user