mirror of
https://github.com/readthedocs/sphinx-autoapi
synced 2024-11-16 00:12:55 +00:00
Updated Autodoc directives for Sphinx 2.1 features
Added autoapidecorator directive. Abides by autodoc_docstring_signature. autoapifunction documents async functions. Closes #166.
This commit is contained in:
parent
34d02faa2f
commit
fd1cef5ced
@ -10,11 +10,15 @@ Features
|
||||
^^^^^^^^
|
||||
|
||||
* (Python) Can read per argument type comments with astroid > 2.2.5.
|
||||
* (Python) Added autoapidecorator directive with Sphinx >= 2.0.
|
||||
* (Python) Can use autodoc_docstring_signature with Autodoc-style directives.
|
||||
|
||||
Bug Fixes
|
||||
^^^^^^^^^
|
||||
|
||||
* (Python) Forward reference annotations are no longer rendered as strings.
|
||||
* (Python) autoapifunction directive no longer documents async functions as
|
||||
a normal function.
|
||||
|
||||
|
||||
v1.1.0 (2019-06-23)
|
||||
|
@ -1,3 +1,6 @@
|
||||
import re
|
||||
|
||||
import sphinx
|
||||
from sphinx.ext import autodoc
|
||||
|
||||
from .mappers.python import (
|
||||
@ -79,7 +82,23 @@ class AutoapiDocumenter(autodoc.Documenter):
|
||||
return False, sorted(children)
|
||||
|
||||
|
||||
class AutoapiFunctionDocumenter(AutoapiDocumenter, autodoc.FunctionDocumenter):
|
||||
class _AutoapiDocstringSignatureMixin(object):
|
||||
def format_signature(self, **kwargs):
|
||||
# Set "manual" attributes at the last possible moment.
|
||||
# This is to let a manual entry or docstring searching happen first,
|
||||
# and falling back to the discovered signature only when necessary.
|
||||
if self.args is None:
|
||||
self.args = self.object.args
|
||||
|
||||
if self.retann is None:
|
||||
self.retann = self.object.return_annotation
|
||||
|
||||
return super(_AutoapiDocstringSignatureMixin, self).format_signature(**kwargs)
|
||||
|
||||
|
||||
class AutoapiFunctionDocumenter(
|
||||
AutoapiDocumenter, autodoc.FunctionDocumenter, _AutoapiDocstringSignatureMixin
|
||||
):
|
||||
objtype = "apifunction"
|
||||
directivetype = "function"
|
||||
# Always prefer AutoapiDocumenters
|
||||
@ -92,18 +111,49 @@ class AutoapiFunctionDocumenter(AutoapiDocumenter, autodoc.FunctionDocumenter):
|
||||
def format_args(self, **kwargs):
|
||||
return "(" + self.object.args + ")"
|
||||
|
||||
def format_signature(self, **kwargs):
|
||||
# Set "introspected" attributes at the last possible minute
|
||||
if self.args is None:
|
||||
self.args = self.object.args
|
||||
def add_directive_header(self, sig):
|
||||
if sphinx.version_info >= (2, 1):
|
||||
autodoc.Documenter.add_directive_header(self, sig)
|
||||
|
||||
if self.retann is None:
|
||||
self.retann = self.object.return_annotation
|
||||
|
||||
return super(AutoapiFunctionDocumenter, self).format_signature(**kwargs)
|
||||
if "async" in self.object.properties:
|
||||
sourcename = self.get_sourcename()
|
||||
self.add_line(" :async:", sourcename)
|
||||
else:
|
||||
super(AutoapiFunctionDocumenter, self).add_directive_header(sig)
|
||||
|
||||
|
||||
class AutoapiClassDocumenter(AutoapiDocumenter, autodoc.ClassDocumenter):
|
||||
if sphinx.version_info >= (2,):
|
||||
|
||||
class AutoapiDecoratorDocumenter(
|
||||
AutoapiFunctionDocumenter, AutoapiDocumenter, autodoc.DecoratorDocumenter
|
||||
):
|
||||
objtype = "apidecorator"
|
||||
directivetype = "decorator"
|
||||
priority = autodoc.DecoratorDocumenter.priority * 100 + 100
|
||||
|
||||
def format_signature(self, **kwargs):
|
||||
if self.args is None:
|
||||
self.args = self.format_args(**kwargs)
|
||||
|
||||
return super(AutoapiDecoratorDocumenter, self).format_signature(**kwargs)
|
||||
|
||||
def format_args(self, **kwargs):
|
||||
to_format = self.object.args
|
||||
|
||||
if re.match("func\W", to_format) or to_format == "func":
|
||||
if "," not in to_format:
|
||||
return None
|
||||
|
||||
# We need to do better stripping here.
|
||||
# An annotation with a comma will mess this up.
|
||||
to_format = self.object.args.split(",", 1)[1]
|
||||
|
||||
return "(" + to_format + ")"
|
||||
|
||||
|
||||
class AutoapiClassDocumenter(
|
||||
AutoapiDocumenter, autodoc.ClassDocumenter, _AutoapiDocstringSignatureMixin
|
||||
):
|
||||
objtype = "apiclass"
|
||||
directivetype = "class"
|
||||
doc_as_attr = False
|
||||
@ -129,7 +179,9 @@ class AutoapiClassDocumenter(AutoapiDocumenter, autodoc.ClassDocumenter):
|
||||
self.add_line(" " + "Bases: {}".format(", ".join(bases)), sourcename)
|
||||
|
||||
|
||||
class AutoapiMethodDocumenter(AutoapiDocumenter, autodoc.MethodDocumenter):
|
||||
class AutoapiMethodDocumenter(
|
||||
AutoapiDocumenter, autodoc.MethodDocumenter, _AutoapiDocstringSignatureMixin
|
||||
):
|
||||
objtype = "apimethod"
|
||||
directivetype = "method"
|
||||
priority = autodoc.MethodDocumenter.priority * 100 + 100
|
||||
@ -141,29 +193,33 @@ class AutoapiMethodDocumenter(AutoapiDocumenter, autodoc.MethodDocumenter):
|
||||
def format_args(self, **kwargs):
|
||||
return "(" + self.object.args + ")"
|
||||
|
||||
def format_signature(self, **kwargs):
|
||||
# Set "introspected" attributes at the last possible minute
|
||||
if self.args is None:
|
||||
self.args = self.object.args
|
||||
|
||||
if self.retann is None:
|
||||
self.retann = self.object.return_annotation
|
||||
|
||||
return super(AutoapiMethodDocumenter, self).format_signature(**kwargs)
|
||||
|
||||
def import_object(self):
|
||||
result = super(AutoapiMethodDocumenter, self).import_object()
|
||||
|
||||
if result:
|
||||
if self.object.method_type != "method":
|
||||
self.directivetype = self.object.method_type
|
||||
if sphinx.version_info < (2, 1):
|
||||
self.directivetype = self.object.method_type
|
||||
# document class and static members before ordinary ones
|
||||
self.member_order = self.member_order - 1
|
||||
|
||||
return result
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
autodoc.Documenter.add_directive_header(self, sig)
|
||||
if sphinx.version_info >= (2, 1):
|
||||
autodoc.Documenter.add_directive_header(self, sig)
|
||||
|
||||
sourcename = self.get_sourcename()
|
||||
for property_type in (
|
||||
"abstractmethod",
|
||||
"async",
|
||||
"classmethod",
|
||||
"staticmethod",
|
||||
):
|
||||
if property_type in self.object.properties:
|
||||
self.add_line(" :{}:".format(property_type), sourcename)
|
||||
else:
|
||||
autodoc.Documenter.add_directive_header(self, sig)
|
||||
|
||||
|
||||
class AutoapiDataDocumenter(AutoapiDocumenter, autodoc.DataDocumenter):
|
||||
|
@ -237,6 +237,8 @@ def setup(app):
|
||||
app.add_config_value("autoapi_python_class_content", "class", "html")
|
||||
app.add_config_value("autoapi_generate_api_docs", True, "html")
|
||||
app.add_autodocumenter(documenters.AutoapiFunctionDocumenter)
|
||||
if sphinx.version_info >= (2,):
|
||||
app.add_autodocumenter(documenters.AutoapiDecoratorDocumenter)
|
||||
app.add_autodocumenter(documenters.AutoapiClassDocumenter)
|
||||
app.add_autodocumenter(documenters.AutoapiMethodDocumenter)
|
||||
app.add_autodocumenter(documenters.AutoapiDataDocumenter)
|
||||
|
@ -93,3 +93,12 @@ class Foo(object):
|
||||
str: A string.
|
||||
"""
|
||||
return "google"
|
||||
|
||||
|
||||
def decorator_okay(func):
|
||||
"""This decorator should parse okay."""
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
@ -4,3 +4,6 @@ Autodoc Directives
|
||||
.. autoapimodule:: example
|
||||
:members:
|
||||
:noindex:
|
||||
|
||||
|
||||
.. autoapidecorator:: example.decorator_okay
|
||||
|
@ -42,8 +42,15 @@ class TestSimpleModule(object):
|
||||
self.check_integration("_build/text/autoapi/example/index.txt")
|
||||
|
||||
def test_manual_directives(self):
|
||||
example_path = "_build/text/manualapi.txt"
|
||||
# The manual directives should contain the same information
|
||||
self.check_integration("_build/text/manualapi.txt")
|
||||
self.check_integration(example_path)
|
||||
|
||||
with io.open(example_path, encoding="utf8") as example_handle:
|
||||
example_file = example_handle.read()
|
||||
|
||||
if sphinx.version_info >= (2,):
|
||||
assert "@example.decorator_okay" in example_file
|
||||
|
||||
def check_integration(self, example_path):
|
||||
with io.open(example_path, encoding="utf8") as example_handle:
|
||||
|
Loading…
Reference in New Issue
Block a user