From 75ec678face6f15153ed28cce5e21fee0eb7d895 Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Thu, 19 Mar 2015 14:20:29 -0400 Subject: [PATCH] This is sort of unrelated, but I found a few cases in testing where this fix was needed. This is more of a followup to #130 to catch some more cases where simply calling getattr() on some objects can result in a non-AttributeError exception. --- .../sphinx/ext/autodoc_enhancements.py | 17 ++++++++++------- astropy_helpers/sphinx/ext/viewcode.py | 5 +++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/astropy_helpers/sphinx/ext/autodoc_enhancements.py b/astropy_helpers/sphinx/ext/autodoc_enhancements.py index ee638141..9a1b64f1 100644 --- a/astropy_helpers/sphinx/ext/autodoc_enhancements.py +++ b/astropy_helpers/sphinx/ext/autodoc_enhancements.py @@ -43,13 +43,16 @@ def type_object_attrgetter(obj, attr, *defargs): of autodoc. """ - if attr in obj.__dict__ and isinstance(obj.__dict__[attr], property): - # Note, this should only be used for properties--for any other type of - # descriptor (classmethod, for example) this can mess up existing - # expectcations of what getattr(cls, ...) returns - return obj.__dict__[attr] - else: - return getattr(obj, attr, *defargs) + for base in obj.__mro__: + if attr in base.__dict__: + if isinstance(base.__dict__[attr], property): + # Note, this should only be used for properties--for any other + # type of descriptor (classmethod, for example) this can mess + # up existing expectations of what getattr(cls, ...) returns + return base.__dict__[attr] + break + + return getattr(obj, attr, *defargs) def setup(app): diff --git a/astropy_helpers/sphinx/ext/viewcode.py b/astropy_helpers/sphinx/ext/viewcode.py index dc428a10..d9fdc612 100644 --- a/astropy_helpers/sphinx/ext/viewcode.py +++ b/astropy_helpers/sphinx/ext/viewcode.py @@ -16,6 +16,7 @@ from sphinx import addnodes from sphinx.locale import _ from sphinx.pycode import ModuleAnalyzer +from sphinx.util.inspect import safe_getattr from sphinx.util.nodes import make_refnode import sys @@ -51,12 +52,12 @@ def get_full_modname(modname, attribute): value = module for attr in attribute.split('.'): if attr: - value = getattr(value, attr) + value = safe_getattr(value, attr) except AttributeError: app.warn('Didn\'t find %s in %s' % (attribute, module.__name__)) return None else: - return getattr(value, '__module__', None) + return safe_getattr(value, '__module__', None) def has_tag(modname, fullname, docname, refname):