1""" 2cloud_sptheme.ext.autoattribute_search_bases -- monkeypatches autodoc so ``autoattribute`` searches base classes for attr doc. 3""" 4#============================================================================= 5# imports 6#============================================================================= 7# core 8import logging; log = logging.getLogger(__name__) 9# site 10# pkg 11from cloud_sptheme import __version__ 12from cloud_sptheme.utils import patchapplier, monkeypatch 13# local 14__all__ = [ 15 "setup", 16] 17 18#============================================================================= 19# patch 20#============================================================================= 21@patchapplier 22def _patch_autoattribute(): 23 from sphinx.ext.autodoc import AttributeDocumenter, ModuleAnalyzer, PycodeError 24 25 @monkeypatch(AttributeDocumenter) 26 def add_content(_wrapped, self, *args, **kwds): 27 if not self._datadescriptor and self.analyzer and self.objpath: 28 attr_docs = self.analyzer.find_attr_docs() 29 key = ('.'.join(self.objpath[:-1]), self.objpath[-1]) 30 if key not in attr_docs: 31 # look for parent class w/ correct attr 32 if hasattr(self.parent, "__mro__"): 33 for basecls in self.parent.__mro__[1:]: 34 try: 35 analyzer = ModuleAnalyzer.for_module(basecls.__module__) 36 base_attr_docs = analyzer.find_attr_docs() 37 except PycodeError as err: 38 continue 39 # FIXME: need qualname or equivalent for basecls 40 base_key = (basecls.__name__, self.objpath[-1]) 41 if base_key in base_attr_docs: 42 # insert data into existing analyzer 43 # XXX: might be prettier way to handle this, 44 # (esp so actual source file was reported) 45 # but would have to duplicate much of add_content() 46 attr_docs[key] = base_attr_docs[base_key] 47 break 48 return _wrapped(self, *args, **kwds) 49 50#============================================================================= 51# sphinx entry point 52#============================================================================= 53def setup(app): 54 # don't apply our patch unless actually loaded by sphinx 55 _patch_autoattribute() 56 57 # identifies the version of our extension 58 return {'version': __version__} 59 60#============================================================================= 61# eoc 62#============================================================================= 63