diff --git a/ci/requirements/doc.yml b/ci/requirements/doc.yml index 658a7d4e47b..e6c99dbacba 100644 --- a/ci/requirements/doc.yml +++ b/ci/requirements/doc.yml @@ -26,3 +26,5 @@ dependencies: - sphinx=3.1 - sphinx_rtd_theme>=0.4 - zarr>=2.4 + - pip: + - sphinx-autosummary-accessors diff --git a/doc/conf.py b/doc/conf.py index d3d126cb33f..2f97c884ff5 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -20,11 +20,7 @@ import sys from contextlib import suppress -# --------- autosummary templates ------------------ -# TODO: eventually replace this with a sphinx.ext.auto_accessor module -import sphinx -from sphinx.ext.autodoc import AttributeDocumenter, Documenter, MethodDocumenter -from sphinx.util import rpartition +import sphinx_autosummary_accessors # make sure the source version is preferred (#3567) root = pathlib.Path(__file__).absolute().parent.parent @@ -53,14 +49,14 @@ matplotlib.use("Agg") try: - import rasterio + import rasterio # noqa: F401 except ImportError: allowed_failures.update( ["gallery/plot_rasterio_rgb.py", "gallery/plot_rasterio.py"] ) try: - import cartopy + import cartopy # noqa: F401 except ImportError: allowed_failures.update( [ @@ -88,6 +84,7 @@ "IPython.sphinxext.ipython_directive", "IPython.sphinxext.ipython_console_highlighting", "nbsphinx", + "sphinx_autosummary_accessors", ] extlinks = { @@ -116,7 +113,7 @@ numpydoc_show_class_members = False # Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] +templates_path = ["_templates", sphinx_autosummary_accessors.templates_path] # The suffix of source filenames. source_suffix = ".rst" @@ -275,14 +272,14 @@ # -- Options for LaTeX output --------------------------------------------- -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # 'preamble': '', -} +# latex_elements = { +# # The paper size ('letterpaper' or 'a4paper'). +# # 'papersize': 'letterpaper', +# # The font size ('10pt', '11pt' or '12pt'). +# # 'pointsize': '10pt', +# # Additional stuff for the LaTeX preamble. +# # 'preamble': '', +# } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, @@ -364,113 +361,3 @@ "dask": ("https://docs.dask.org/en/latest", None), "cftime": ("https://unidata.github.io/cftime", None), } - - -# --------- autosummary templates ------------------ -# TODO: eventually replace this with a sphinx.ext.auto_accessor module -class AccessorDocumenter(MethodDocumenter): - """ - Specialized Documenter subclass for accessors. - """ - - objtype = "accessor" - directivetype = "method" - - # lower than MethodDocumenter so this is not chosen for normal methods - priority = 0.6 - - def format_signature(self): - # this method gives an error/warning for the accessors, therefore - # overriding it (accessor has no arguments) - return "" - - -class AccessorLevelDocumenter(Documenter): - """ - Specialized Documenter subclass for objects on accessor level (methods, - attributes). - """ - - # This is the simple straightforward version - # modname is None, base the last elements (eg 'hour') - # and path the part before (eg 'Series.dt') - # def resolve_name(self, modname, parents, path, base): - # modname = 'pandas' - # mod_cls = path.rstrip('.') - # mod_cls = mod_cls.split('.') - # - # return modname, mod_cls + [base] - - def resolve_name(self, modname, parents, path, base): - if modname is None: - if path: - mod_cls = path.rstrip(".") - else: - mod_cls = None - # if documenting a class-level object without path, - # there must be a current class, either from a parent - # auto directive ... - mod_cls = self.env.temp_data.get("autodoc:class") - # ... or from a class directive - if mod_cls is None: - mod_cls = self.env.temp_data.get("py:class") - # ... if still None, there's no way to know - if mod_cls is None: - return None, [] - # HACK: this is added in comparison to ClassLevelDocumenter - # mod_cls still exists of class.accessor, so an extra - # rpartition is needed - modname, accessor = rpartition(mod_cls, ".") - modname, cls = rpartition(modname, ".") - parents = [cls, accessor] - # if the module name is still missing, get it like above - if not modname: - modname = self.env.temp_data.get("autodoc:module") - if not modname: - if sphinx.__version__ > "1.3": - modname = self.env.ref_context.get("py:module") - else: - modname = self.env.temp_data.get("py:module") - # ... else, it stays None, which means invalid - return modname, parents + [base] - - -class AccessorAttributeDocumenter(AccessorLevelDocumenter, AttributeDocumenter): - - objtype = "accessorattribute" - directivetype = "attribute" - - # lower than AttributeDocumenter so this is not chosen for normal attributes - priority = 0.6 - - -class AccessorMethodDocumenter(AccessorLevelDocumenter, MethodDocumenter): - - objtype = "accessormethod" - directivetype = "method" - - # lower than MethodDocumenter so this is not chosen for normal methods - priority = 0.6 - - -class AccessorCallableDocumenter(AccessorLevelDocumenter, MethodDocumenter): - """ - This documenter lets us removes .__call__ from the method signature for - callable accessors like Series.plot - """ - - objtype = "accessorcallable" - directivetype = "method" - - # lower than MethodDocumenter; otherwise the doc build prints warnings - priority = 0.5 - - def format_name(self): - return MethodDocumenter.format_name(self).rstrip(".__call__") - - -def setup(app): - app.add_autodocumenter(AccessorDocumenter) - app.add_autodocumenter(AccessorAttributeDocumenter) - app.add_autodocumenter(AccessorMethodDocumenter) - app.add_autodocumenter(AccessorCallableDocumenter) diff --git a/doc/internals.rst b/doc/internals.rst index b158f12ac6d..aa9e1dedc68 100644 --- a/doc/internals.rst +++ b/doc/internals.rst @@ -171,6 +171,11 @@ To help users keep things straight, please `let us know for an open source library. In the future, we will maintain a list of accessors and the libraries that implement them on this page. +To make documenting accessors with ``sphinx`` and ``sphinx.ext.autosummary`` +easier, you can use `sphinx-ext-autosummary`_. + +.. _sphinx-ext-autosummary: https://sphinx-autosummary-accessors.readthedocs.io/ + .. _zarr_encoding: Zarr Encoding Specification