Skip to content

Commit

Permalink
replace the hack with the feature from sphinx-doc/sphinx#8038
Browse files Browse the repository at this point in the history
  • Loading branch information
keewis committed Aug 7, 2020
1 parent c26ebce commit 3e2ab81
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 137 deletions.
20 changes: 11 additions & 9 deletions sphinx_autosummary_accessors/__init__.py
Expand Up @@ -5,7 +5,7 @@

import pathlib

import packaging.version
import packaging
import sphinx

from .documenters import (
Expand All @@ -15,12 +15,6 @@
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 +23,12 @@
templates_path = str(pathlib.Path(__file__).parent / "templates")


def add_autosummary_get_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 +37,7 @@ def setup(app):
app.add_autodocumenter(AccessorMethodDocumenter)
app.add_autodocumenter(AccessorCallableDocumenter)

if CustomAutosummary is not None:
app.add_directive("autosummary", CustomAutosummary, override=True)
if packaging.version.parse(sphinx.__version__) >= packaging.version.parse("3.2.0"):
from .autosummary import create_documenter_from_template

add_autosummary_get_documenter(create_documenter_from_template)
158 changes: 30 additions & 128 deletions sphinx_autosummary_accessors/autosummary.py
@@ -1,7 +1,10 @@
import re

from sphinx.ext import autosummary
from sphinx.ext.autosummary import Autosummary, __, generate
from sphinx.ext.autosummary import Autosummary, generate

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


def extract_documenter(content):
Expand All @@ -15,135 +18,34 @@ def extract_documenter(content):
return directive_name, "::".join([modname, name])


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

def get_items(self, names):
"""Try to import the given names, and return a list of
``[(name, signature, summary_string, real_name), ...]``.
"""
prefixes = autosummary.get_import_prefixes_from_env(self.env)

items = []

max_item_chars = 50

for name in names:
display_name = name
if name.startswith("~"):
name = name[1:]
display_name = name.split(".")[-1]

try:
with autosummary.mock(self.config.autosummary_mock_imports):
real_name, obj, parent, modname = autosummary.import_by_name(
name, prefixes=prefixes
)
except ImportError:
autosummary.logger.warning(
__("autosummary: failed to import %s"),
name,
location=self.get_source_info(),
)
continue

# initialize for each documenter
self.bridge.result = autosummary.StringList()
full_name = real_name
if not isinstance(obj, autosummary.ModuleType):
# give explicitly separated module name, so that members
# of inner classes can be documented
full_name = modname + "::" + full_name[len(modname) + 1 :]
# 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 = doccls(self.bridge, full_name)
if not documenter.parse_name():
autosummary.logger.warning(
__("failed to parse name %s"),
real_name,
location=self.get_source_info(),
)
items.append((display_name, "", "", real_name))
continue
if not documenter.import_object():
autosummary.logger.warning(
__("failed to import object %s"),
real_name,
location=self.get_source_info(),
)
items.append((display_name, "", "", real_name))
continue
if documenter.options.members and not documenter.check_module():
continue

# try to also get a source code analyzer for attribute docs
try:
documenter.analyzer = autosummary.ModuleAnalyzer.for_module(
documenter.get_real_modname()
)
# parse right now, to get PycodeErrors on parsing (results will
# be cached anyway)
documenter.analyzer.find_attr_docs()
except autosummary.PycodeError as err:
autosummary.logger.debug("[autodoc] module analyzer failed: %s", err)
# no source file -- e.g. for builtin and C modules
documenter.analyzer = None

# -- Grab the signature
def create_documenter_from_template(autosummary, app, obj, parent, full_name):
real_name = ".".join(full_name.split("::"))

try:
sig = documenter.format_signature(show_annotation=False)
except TypeError:
# the documenter does not support ``show_annotation`` option
sig = documenter.format_signature()
options = autosummary.options.copy()
template_name = options.pop("template")
if template_name is None:
return original_create_documenter(autosummary, app, obj, parent, full_name)

if not sig:
sig = ""
else:
max_chars = max(10, max_item_chars - len(display_name))
sig = autosummary.mangle_signature(sig, max_chars=max_chars)
options.pop("toctree")
options["imported_members"] = options.get("imported_members", False)
options["recursive"] = options.get("recursive", False)

# -- Grab the summary
context = {}
context.update(app.config.autosummary_context)

documenter.add_content(None)
summary = autosummary.extract_summary(
self.bridge.result.data[:], self.state.document
)
rendered = generate.generate_autosummary_content(
real_name,
obj,
parent,
template=generate.AutosummaryRenderer(app),
template_name=template_name,
app=app,
context=context,
**options,
)

items.append((display_name, sig, summary, real_name))
documenter_name, real_name = extract_documenter(rendered)
doccls = app.registry.documenters.get(documenter_name)
documenter = doccls(autosummary.bridge, full_name)

return items
return documenter

0 comments on commit 3e2ab81

Please sign in to comment.