|
162 | 162 | # they have a caption.
|
163 | 163 | numfig = True
|
164 | 164 |
|
| 165 | + |
| 166 | +# We want to be able to document the CONFIG class attribute in a special |
| 167 | +# section. Nominally, we would use the napoleon_custom_sections hook. |
| 168 | +# Unfortunately, there isn't a generic "kwargs_style", and aliasing |
| 169 | +# 'Keyword Arguments' would render the section header in the |
| 170 | +# documentation as 'Keyword Arguments'. |
| 171 | +# |
| 172 | +# Our solution is to declare a new PyObject field type (:config:) and |
| 173 | +# define a new parser that generates :config: fields. We register the |
| 174 | +# new parser with Napoleon by monkey-patching _load_custom_sections(). |
| 175 | +def _monkey_patch_napoleon(): |
| 176 | + from sphinx.ext.napoleon.docstring import GoogleDocstring |
| 177 | + from sphinx.domains.python._object import PyObject, PyTypedField |
| 178 | + from sphinx.locale import _ |
| 179 | + from sphinx import addnodes |
| 180 | + from functools import partial |
| 181 | + |
| 182 | + class PyConfigDomainField(PyTypedField): |
| 183 | + def make_xref( |
| 184 | + self, |
| 185 | + rolename: str, |
| 186 | + domain: str, |
| 187 | + target: str, |
| 188 | + innernode=addnodes.literal_emphasis, |
| 189 | + contnode=None, |
| 190 | + env=None, |
| 191 | + inliner=None, |
| 192 | + location=None, |
| 193 | + ): |
| 194 | + ans = super().make_xref( |
| 195 | + rolename=rolename, |
| 196 | + domain=domain, |
| 197 | + target=target, |
| 198 | + innernode=innernode, |
| 199 | + contnode=contnode, |
| 200 | + env=env, |
| 201 | + inliner=inliner, |
| 202 | + location=location, |
| 203 | + ) |
| 204 | + # Part of the call stack will override the reftype to |
| 205 | + # "class". We want to support a broader set of domain |
| 206 | + # types, so we will set it to "anything" (i.e., object) |
| 207 | + ans['reftype'] = 'obj' |
| 208 | + return ans |
| 209 | + |
| 210 | + PyObject.doc_field_types.append( |
| 211 | + PyConfigDomainField( |
| 212 | + 'config', |
| 213 | + label=_('CONFIG'), |
| 214 | + names=('config',), |
| 215 | + typerolename='obj', |
| 216 | + typenames=('configtype',), |
| 217 | + can_collapse=True, |
| 218 | + ) |
| 219 | + ) |
| 220 | + PyObject.doc_field_types.append( |
| 221 | + PyConfigDomainField( |
| 222 | + 'option', |
| 223 | + label=_('Options'), |
| 224 | + names=('option',), |
| 225 | + typerolename='obj', |
| 226 | + typenames=('optiontype',), |
| 227 | + can_collapse=True, |
| 228 | + ) |
| 229 | + ) |
| 230 | + |
| 231 | + def _parse_config_section(self, field: str, section: str) -> list[str]: |
| 232 | + fields = self._consume_fields() |
| 233 | + if self._config.napoleon_use_keyword: |
| 234 | + return self._format_docutils_params( |
| 235 | + fields, field_role=field, type_role=field + 'type' |
| 236 | + ) |
| 237 | + else: |
| 238 | + return self._format_fields(_(section), fields) |
| 239 | + |
| 240 | + original_loader = GoogleDocstring._load_custom_sections |
| 241 | + |
| 242 | + def _load_custom_sections(self): |
| 243 | + self._sections['config'] = partial(self._parse_config_section, 'config') |
| 244 | + self._sections['options'] = partial(self._parse_config_section, 'option') |
| 245 | + return original_loader(self) |
| 246 | + |
| 247 | + GoogleDocstring._parse_config_section = _parse_config_section |
| 248 | + GoogleDocstring._load_custom_sections = _load_custom_sections |
| 249 | + |
| 250 | + |
| 251 | +_monkey_patch_napoleon() |
| 252 | + |
165 | 253 | # -- Options for HTML output ----------------------------------------------
|
166 | 254 |
|
167 | 255 | # The theme to use for HTML and HTML Help pages. See the documentation for
|
|
0 commit comments