770a4bbb4a
sphinx.domain.python got split[0] into multiple modules so make the
sphinx extension work with older and newer Sphinx versions.
[0]
e9dcfebcf9
Change-Id: I2dfb085cd382e277562f4dcb3d903729dc388fd4
150 lines
5.0 KiB
Python
150 lines
5.0 KiB
Python
# Copyright 2012 Hewlett-Packard Development Company, L.P.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
# Most of this code originated in sphinx.domains.python and
|
|
# sphinx.ext.autodoc and has been only slightly adapted for use in
|
|
# subclasses here.
|
|
|
|
# :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
|
|
# :license: BSD, see LICENSE for details.
|
|
|
|
import re
|
|
|
|
from sphinx import addnodes
|
|
|
|
try:
|
|
from sphinx.domains.python._annotations import _pseudo_parse_arglist
|
|
except ImportError:
|
|
from sphinx.domains.python import _pseudo_parse_arglist
|
|
from sphinx.domains.python import PyFunction, PyXRefRole
|
|
from sphinx.ext.autodoc import Documenter
|
|
from sphinx.ext.autodoc import FunctionDocumenter
|
|
from sphinx.locale import _
|
|
|
|
|
|
yaml_sig_re = re.compile(r"yaml:\s*(.*)")
|
|
|
|
|
|
class PyYAMLFunction(PyFunction):
|
|
def handle_signature(self, sig, signode):
|
|
"""Transform a Python signature into RST nodes.
|
|
|
|
Return (fully qualified name of the thing, classname if any).
|
|
|
|
If inside a class, the current class name is handled intelligently:
|
|
* it is stripped from the displayed name if present
|
|
* it is added to the full name (return value) if not present
|
|
"""
|
|
name_prefix = None
|
|
name = sig
|
|
arglist = None
|
|
retann = None
|
|
|
|
# determine module and class name (if applicable), as well as full name
|
|
modname = self.options.get("module", self.env.temp_data.get("py:module"))
|
|
classname = self.env.temp_data.get("py:class")
|
|
|
|
fullname = name
|
|
|
|
signode["module"] = modname
|
|
signode["class"] = classname
|
|
signode["fullname"] = fullname
|
|
|
|
sig_prefix = self.get_signature_prefix(sig)
|
|
if sig_prefix:
|
|
signode += addnodes.desc_annotation(sig_prefix, sig_prefix)
|
|
|
|
if name_prefix:
|
|
signode += addnodes.desc_addname(name_prefix, name_prefix)
|
|
|
|
anno = self.options.get("annotation")
|
|
|
|
signode += addnodes.desc_name(name, name)
|
|
if not arglist:
|
|
if self.needs_arglist():
|
|
# for callables, add an empty parameter list
|
|
signode += addnodes.desc_parameterlist()
|
|
if retann:
|
|
signode += addnodes.desc_returns(retann, retann)
|
|
if anno:
|
|
signode += addnodes.desc_annotation(" " + anno, " " + anno)
|
|
return fullname, name_prefix
|
|
|
|
_pseudo_parse_arglist(signode, arglist)
|
|
if retann:
|
|
signode += addnodes.desc_returns(retann, retann)
|
|
if anno:
|
|
signode += addnodes.desc_annotation(" " + anno, " " + anno)
|
|
return fullname, name_prefix
|
|
|
|
def get_index_text(self, modname, name_cls):
|
|
return _("%s (in module %s)") % (name_cls[0], modname)
|
|
|
|
|
|
class YAMLFunctionDocumenter(FunctionDocumenter):
|
|
priority = FunctionDocumenter.priority + 10
|
|
objtype = "yamlfunction"
|
|
directivetype = "yamlfunction"
|
|
|
|
@classmethod
|
|
def can_document_member(cls, member, membername, isattr, parent):
|
|
if not FunctionDocumenter.can_document_member(
|
|
member, membername, isattr, parent
|
|
):
|
|
return False
|
|
if member.__doc__ is not None and yaml_sig_re.match(member.__doc__):
|
|
return True
|
|
return False
|
|
|
|
def _find_signature(self, encoding=None):
|
|
docstrings = Documenter.get_doc(self)
|
|
if len(docstrings) != 1:
|
|
return
|
|
doclines = docstrings[0]
|
|
setattr(self, "__new_doclines", doclines)
|
|
if not doclines:
|
|
return
|
|
# match first line of docstring against signature RE
|
|
match = yaml_sig_re.match(doclines[0])
|
|
if not match:
|
|
return
|
|
name = match.group(1)
|
|
# ok, now jump over remaining empty lines and set the remaining
|
|
# lines as the new doclines
|
|
i = 1
|
|
while i < len(doclines) and not doclines[i].strip():
|
|
i += 1
|
|
setattr(self, "__new_doclines", doclines[i:])
|
|
return name
|
|
|
|
def get_doc(self, encoding=None, ignore=1):
|
|
lines = getattr(self, "__new_doclines", None)
|
|
if lines is not None:
|
|
return [lines]
|
|
return Documenter.get_doc(self)
|
|
|
|
def format_signature(self):
|
|
result = self._find_signature()
|
|
self._name = result
|
|
return ""
|
|
|
|
def format_name(self):
|
|
return self._name
|
|
|
|
|
|
def setup(app):
|
|
app.add_autodocumenter(YAMLFunctionDocumenter)
|
|
app.add_directive_to_domain("py", "yamlfunction", PyYAMLFunction)
|
|
app.add_role_to_domain("py", "yamlfunction", PyXRefRole())
|