Georg Brandl avatar Georg Brandl committed fe2021d

#229: Fix autodoc failures with members that raise errors
on ``getattr()``.

Comments (0)

Files changed (3)

 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.
 

sphinx/ext/autodoc.py

 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
 
 
     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
                                         % (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
             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:

sphinx/util/inspect.py

+# -*- 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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.