Skip to content

Commit

Permalink
use a custom create_documenter function (#10)
Browse files Browse the repository at this point in the history
* use the new create_documenter hook, with a fall back to the hook

* update the requirements for docs

* add a warning about callables only being fully supported from 3.1 onwards

* fix the signature of callable accessors
  • Loading branch information
keewis committed Aug 7, 2020
1 parent 9194927 commit 899d886
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 45 deletions.
8 changes: 7 additions & 1 deletion docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,15 @@ becomes:

Callable accessors can be documented, too:

.. warning::

This feature is only fully supported from sphinx version 3.1 onwards. On
earlier versions, the summary will claim this is a alias of the
accessor class.

.. literalinclude:: examples.rst
:language: rst
:lines: 46-50
:lines: 52-56

becomes:

Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sphinx
sphinx>=3.1
sphinx_rtd_theme
packaging
importlib-metadata; python_version < "3.8"
22 changes: 13 additions & 9 deletions sphinx_autosummary_accessors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,17 @@

import pathlib

import packaging.version
import packaging
import sphinx

from . import autosummary
from .documenters import (
AccessorAttributeDocumenter,
AccessorCallableDocumenter,
AccessorDocumenter,
AccessorMethodDocumenter,
)

if packaging.version.parse(sphinx.__version__) >= packaging.version.parse("3.1"):
from .autosummary import CustomAutosummary
else:
CustomAutosummary = None


try:
__version__ = version("sphinx-autosummary-accessors")
except Exception:
Expand All @@ -29,6 +24,12 @@
templates_path = str(pathlib.Path(__file__).parent / "templates")


def add_autosummary_create_documenter(func):
import sphinx.ext.autosummary

sphinx.ext.autosummary.Autosummary.create_documenter = func


def setup(app):
app.setup_extension("sphinx.ext.autosummary")

Expand All @@ -37,5 +38,8 @@ def setup(app):
app.add_autodocumenter(AccessorMethodDocumenter)
app.add_autodocumenter(AccessorCallableDocumenter)

if CustomAutosummary is not None:
app.add_directive("autosummary", CustomAutosummary, override=True)
sphinx_version = packaging.version.parse(sphinx.__version__)
if sphinx_version >= packaging.version.parse("3.2"):
add_autosummary_create_documenter(autosummary.create_documenter_from_template)
elif sphinx_version >= packaging.version.parse("3.1"):
app.add_directive("autosummary", autosummary.CustomAutosummary, override=True)
73 changes: 39 additions & 34 deletions sphinx_autosummary_accessors/autosummary.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
from sphinx.ext import autosummary
from sphinx.ext.autosummary import Autosummary, __, generate

original_create_documenter = getattr(
Autosummary, "create_documenter", lambda *args: None
)


def extract_documenter(content):
directives_re = re.compile(r"^\.\. ([^:]+):: (.+)$", re.MULTILINE)
Expand All @@ -15,34 +19,41 @@ def extract_documenter(content):
return directive_name, "::".join([modname, name])


def create_documenter_from_template(autosummary, app, obj, parent, full_name):
real_name = ".".join(full_name.split("::"))

options = autosummary.options.copy()
template_name = options.pop("template")
if template_name is None:
return original_create_documenter(autosummary, app, obj, parent, full_name)

options.pop("toctree")
options["imported_members"] = options.get("imported_members", False)
options["recursive"] = options.get("recursive", False)

context = {}
context.update(app.config.autosummary_context)

rendered = generate.generate_autosummary_content(
real_name,
obj,
parent,
template=generate.AutosummaryRenderer(app),
template_name=template_name,
app=app,
context=context,
**options,
)

documenter_name, real_name = extract_documenter(rendered)
doccls = app.registry.documenters.get(documenter_name)
documenter = doccls(autosummary.bridge, real_name)

return documenter


class CustomAutosummary(Autosummary):
def get_documenter_from_template(self, name, obj, parent, options):
options = options.copy()
options.pop("toctree")
template_name = options.pop("template")
options["imported_members"] = options.get("imported_members", False)
options["recursive"] = options.get("recursive", False)

app = self.env.app

context = {}
context.update(app.config.autosummary_context)

rendered = generate.generate_autosummary_content(
name,
obj,
parent,
template=generate.AutosummaryRenderer(app),
template_name=template_name,
app=app,
context=context,
**options,
)

documenter_name, real_name = extract_documenter(rendered)
documenter = app.registry.documenters.get(documenter_name)

return documenter, real_name
create_documenter = create_documenter_from_template

def get_items(self, names):
"""Try to import the given names, and return a list of
Expand Down Expand Up @@ -83,14 +94,8 @@ def get_items(self, names):
# NB. using full_name here is important, since Documenters
# handle module prefixes slightly differently

if "template" in self.options:
doccls, full_name = self.get_documenter_from_template(
real_name, obj, parent, self.options
)
else:
doccls = autosummary.get_documenter(self.env.app, obj, parent)
documenter = self.create_documenter(self.env.app, obj, parent, full_name)

documenter = doccls(self.bridge, full_name)
if not documenter.parse_name():
autosummary.logger.warning(
__("failed to parse name %s"),
Expand Down

0 comments on commit 899d886

Please sign in to comment.