/doc/source/conf.py
Python | 770 lines | 725 code | 14 blank | 31 comment | 24 complexity | 9cbbeb1d0352c66cd5d22f79bfb008b1 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
- # -*- coding: utf-8 -*-
- #
- # pandas documentation build configuration file, created by
- #
- # This file is execfile()d with the current directory set to its containing
- # dir.
- #
- # Note that not all possible configuration values are present in this
- # autogenerated file.
- #
- # All configuration values have a default; values that are commented out
- # serve to show the default.
- import sys
- import os
- import inspect
- import importlib
- import logging
- import warnings
- import jinja2
- from sphinx.ext.autosummary import _import_by_name
- from numpydoc.docscrape import NumpyDocString
- from numpydoc.docscrape_sphinx import SphinxDocString
- logger = logging.getLogger(__name__)
- # https://github.com/sphinx-doc/sphinx/pull/2325/files
- # Workaround for sphinx-build recursion limit overflow:
- # pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
- # RuntimeError: maximum recursion depth exceeded while pickling an object
- #
- # Python's default allowed recursion depth is 1000.
- sys.setrecursionlimit(5000)
- # If extensions (or modules to document with autodoc) are in another directory,
- # add these directories to sys.path here. If the directory is relative to the
- # documentation root, use os.path.abspath to make it absolute, like shown here.
- # sys.path.append(os.path.abspath('.'))
- sys.path.insert(0, os.path.abspath('../sphinxext'))
- sys.path.extend([
- # numpy standard doc extensions
- os.path.join(os.path.dirname(__file__),
- '..', '../..',
- 'sphinxext')
- ])
- # -- General configuration -----------------------------------------------
- # Add any Sphinx extension module names here, as strings. They can be
- # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
- # sphinxext.
- extensions = ['sphinx.ext.autodoc',
- 'sphinx.ext.autosummary',
- 'sphinx.ext.doctest',
- 'sphinx.ext.extlinks',
- 'sphinx.ext.todo',
- 'numpydoc', # handle NumPy documentation formatted docstrings
- 'IPython.sphinxext.ipython_directive',
- 'IPython.sphinxext.ipython_console_highlighting',
- 'matplotlib.sphinxext.plot_directive',
- 'sphinx.ext.intersphinx',
- 'sphinx.ext.coverage',
- 'sphinx.ext.mathjax',
- 'sphinx.ext.ifconfig',
- 'sphinx.ext.linkcode',
- 'nbsphinx',
- 'contributors', # custom pandas extension
- ]
- exclude_patterns = ['**.ipynb_checkpoints']
- try:
- import nbconvert
- except ImportError:
- logger.warn('nbconvert not installed. Skipping notebooks.')
- exclude_patterns.append('**/*.ipynb')
- else:
- try:
- nbconvert.utils.pandoc.get_pandoc_version()
- except nbconvert.utils.pandoc.PandocMissing:
- logger.warn('Pandoc not installed. Skipping notebooks.')
- exclude_patterns.append('**/*.ipynb')
- # sphinx_pattern can be '-api' to exclude the API pages,
- # the path to a file, or a Python object
- # (e.g. '10min.rst' or 'pandas.DataFrame.head')
- source_path = os.path.dirname(os.path.abspath(__file__))
- pattern = os.environ.get('SPHINX_PATTERN')
- if pattern:
- for dirname, dirs, fnames in os.walk(source_path):
- for fname in fnames:
- if os.path.splitext(fname)[-1] in ('.rst', '.ipynb'):
- fname = os.path.relpath(os.path.join(dirname, fname),
- source_path)
- if (fname == 'index.rst'
- and os.path.abspath(dirname) == source_path):
- continue
- elif pattern == '-api' and dirname == 'reference':
- exclude_patterns.append(fname)
- elif pattern != '-api' and fname != pattern:
- exclude_patterns.append(fname)
- with open(os.path.join(source_path, 'index.rst.template')) as f:
- t = jinja2.Template(f.read())
- with open(os.path.join(source_path, 'index.rst'), 'w') as f:
- f.write(t.render(include_api=pattern is None,
- single_doc=(pattern
- if pattern is not None and pattern != '-api'
- else None)))
- autosummary_generate = True if pattern is None else ['index']
- # matplotlib plot directive
- plot_include_source = True
- plot_formats = [("png", 90)]
- plot_html_show_formats = False
- plot_html_show_source_link = False
- plot_pre_code = """import numpy as np
- import pandas as pd"""
- # Add any paths that contain templates here, relative to this directory.
- templates_path = ['../_templates']
- # The suffix of source filenames.
- source_suffix = [
- '.rst',
- ]
- # The encoding of source files.
- source_encoding = 'utf-8'
- # The master toctree document.
- master_doc = 'index'
- # General information about the project.
- project = u'pandas'
- copyright = u'2008-2014, the pandas development team'
- # The version info for the project you're documenting, acts as replacement for
- # |version| and |release|, also used in various other places throughout the
- # built documents.
- #
- # The short X.Y version.
- import pandas
- # version = '%s r%s' % (pandas.__version__, svn_version())
- version = str(pandas.__version__)
- # The full version, including alpha/beta/rc tags.
- release = version
- # The language for content autogenerated by Sphinx. Refer to documentation
- # for a list of supported languages.
- # language = None
- # There are two options for replacing |today|: either, you set today to some
- # non-false value, then it is used:
- # today = ''
- # Else, today_fmt is used as the format for a strftime call.
- # today_fmt = '%B %d, %Y'
- # List of documents that shouldn't be included in the build.
- # unused_docs = []
- # List of directories, relative to source directory, that shouldn't be searched
- # for source files.
- exclude_trees = []
- # The reST default role (used for this markup: `text`) to use for all
- # documents. default_role = None
- # If true, '()' will be appended to :func: etc. cross-reference text.
- # add_function_parentheses = True
- # If true, the current module name will be prepended to all description
- # unit titles (such as .. function::).
- # add_module_names = True
- # If true, sectionauthor and moduleauthor directives will be shown in the
- # output. They are ignored by default.
- # show_authors = False
- # The name of the Pygments (syntax highlighting) style to use.
- pygments_style = 'sphinx'
- # A list of ignored prefixes for module index sorting.
- # modindex_common_prefix = []
- # -- Options for HTML output ---------------------------------------------
- # The theme to use for HTML and HTML Help pages. Major themes that come with
- # Sphinx are currently 'default' and 'sphinxdoc'.
- html_theme = 'nature_with_gtoc'
- # The style sheet to use for HTML and HTML Help pages. A file of that name
- # must exist either in Sphinx' static/ path, or in one of the custom paths
- # given in html_static_path.
- # html_style = 'statsmodels.css'
- # Theme options are theme-specific and customize the look and feel of a theme
- # further. For a list of options available for each theme, see the
- # documentation.
- # html_theme_options = {}
- # Add any paths that contain custom themes here, relative to this directory.
- html_theme_path = ['themes']
- # The name for this set of Sphinx documents. If None, it defaults to
- # "<project> v<release> documentation".
- # html_title = None
- # A shorter title for the navigation bar. Default is the same as html_title.
- # html_short_title = None
- # The name of an image file (relative to this directory) to place at the top
- # of the sidebar.
- # html_logo = None
- # Add any paths that contain custom static files (such as style sheets) here,
- # relative to this directory. They are copied after the builtin static files,
- # so a file named "default.css" will overwrite the builtin "default.css".
- html_static_path = ['_static']
- # The name of an image file (within the static path) to use as favicon of the
- # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
- # pixels large.
- html_favicon = os.path.join(html_static_path[0], 'favicon.ico')
- # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
- # using the given strftime format.
- # html_last_updated_fmt = '%b %d, %Y'
- # If true, SmartyPants will be used to convert quotes and dashes to
- # typographically correct entities.
- # html_use_smartypants = True
- # Custom sidebar templates, maps document names to template names.
- # html_sidebars = {}
- # Additional templates that should be rendered to pages, maps page names to
- # template names.
- # Add redirect for previously existing API pages
- # each item is like `(from_old, to_new)`
- # To redirect a class and all its methods, see below
- # https://github.com/pandas-dev/pandas/issues/16186
- moved_api_pages = [
- ('pandas.core.common.isnull', 'pandas.isna'),
- ('pandas.core.common.notnull', 'pandas.notna'),
- ('pandas.core.reshape.get_dummies', 'pandas.get_dummies'),
- ('pandas.tools.merge.concat', 'pandas.concat'),
- ('pandas.tools.merge.merge', 'pandas.merge'),
- ('pandas.tools.pivot.pivot_table', 'pandas.pivot_table'),
- ('pandas.tseries.tools.to_datetime', 'pandas.to_datetime'),
- ('pandas.io.clipboard.read_clipboard', 'pandas.read_clipboard'),
- ('pandas.io.excel.ExcelFile.parse', 'pandas.ExcelFile.parse'),
- ('pandas.io.excel.read_excel', 'pandas.read_excel'),
- ('pandas.io.gbq.read_gbq', 'pandas.read_gbq'),
- ('pandas.io.html.read_html', 'pandas.read_html'),
- ('pandas.io.json.read_json', 'pandas.read_json'),
- ('pandas.io.parsers.read_csv', 'pandas.read_csv'),
- ('pandas.io.parsers.read_fwf', 'pandas.read_fwf'),
- ('pandas.io.parsers.read_table', 'pandas.read_table'),
- ('pandas.io.pickle.read_pickle', 'pandas.read_pickle'),
- ('pandas.io.pytables.HDFStore.append', 'pandas.HDFStore.append'),
- ('pandas.io.pytables.HDFStore.get', 'pandas.HDFStore.get'),
- ('pandas.io.pytables.HDFStore.put', 'pandas.HDFStore.put'),
- ('pandas.io.pytables.HDFStore.select', 'pandas.HDFStore.select'),
- ('pandas.io.pytables.read_hdf', 'pandas.read_hdf'),
- ('pandas.io.sql.read_sql', 'pandas.read_sql'),
- ('pandas.io.sql.read_frame', 'pandas.read_frame'),
- ('pandas.io.sql.write_frame', 'pandas.write_frame'),
- ('pandas.io.stata.read_stata', 'pandas.read_stata'),
- ]
- # Again, tuples of (from_old, to_new)
- moved_classes = [
- ('pandas.tseries.resample.Resampler', 'pandas.core.resample.Resampler'),
- ('pandas.formats.style.Styler', 'pandas.io.formats.style.Styler'),
- ]
- for old, new in moved_classes:
- # the class itself...
- moved_api_pages.append((old, new))
- mod, classname = new.rsplit('.', 1)
- klass = getattr(importlib.import_module(mod), classname)
- methods = [x for x in dir(klass)
- if not x.startswith('_') or x in ('__iter__', '__array__')]
- for method in methods:
- # ... and each of its public methods
- moved_api_pages.append(
- ("{old}.{method}".format(old=old, method=method),
- "{new}.{method}".format(new=new, method=method))
- )
- if pattern is None:
- html_additional_pages = {
- 'generated/' + page[0]: 'api_redirect.html'
- for page in moved_api_pages
- }
- header = """\
- .. currentmodule:: pandas
- .. ipython:: python
- :suppress:
- import numpy as np
- import pandas as pd
- randn = np.random.randn
- np.random.seed(123456)
- np.set_printoptions(precision=4, suppress=True)
- pd.options.display.max_rows = 15
- import os
- os.chdir('{}')
- """.format(os.path.dirname(os.path.dirname(__file__)))
- html_context = {
- 'redirects': {old: new for old, new in moved_api_pages},
- 'header': header
- }
- # If false, no module index is generated.
- html_use_modindex = True
- # If false, no index is generated.
- # html_use_index = True
- # If true, the index is split into individual pages for each letter.
- # html_split_index = False
- # If true, links to the reST sources are added to the pages.
- # html_show_sourcelink = True
- # If true, an OpenSearch description file will be output, and all pages will
- # contain a <link> tag referring to it. The value of this option must be the
- # base URL from which the finished HTML is served.
- # html_use_opensearch = ''
- # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
- # html_file_suffix = ''
- # Output file base name for HTML help builder.
- htmlhelp_basename = 'pandas'
- # -- Options for nbsphinx ------------------------------------------------
- nbsphinx_allow_errors = True
- # -- Options for LaTeX output --------------------------------------------
- latex_elements = {}
- # The paper size ('letter' or 'a4').
- # latex_paper_size = 'letter'
- # The font size ('10pt', '11pt' or '12pt').
- # latex_font_size = '10pt'
- # Grouping the document tree into LaTeX files. List of tuples (source start
- # file, target name, title, author, documentclass [howto/manual]).
- latex_documents = [
- ('index', 'pandas.tex',
- 'pandas: powerful Python data analysis toolkit',
- r'Wes McKinney\n\& PyData Development Team', 'manual'),
- ]
- # The name of an image file (relative to this directory) to place at the top of
- # the title page.
- # latex_logo = None
- # For "manual" documents, if this is true, then toplevel headings are parts,
- # not chapters.
- # latex_use_parts = False
- # Additional stuff for the LaTeX preamble.
- # latex_preamble = ''
- # Documents to append as an appendix to all manuals.
- # latex_appendices = []
- # If false, no module index is generated.
- # latex_use_modindex = True
- if pattern is None:
- intersphinx_mapping = {
- 'dateutil': ("https://dateutil.readthedocs.io/en/latest/", None),
- 'matplotlib': ('https://matplotlib.org/', None),
- 'numpy': ('https://docs.scipy.org/doc/numpy/', None),
- 'pandas-gbq': ('https://pandas-gbq.readthedocs.io/en/latest/', None),
- 'py': ('https://pylib.readthedocs.io/en/latest/', None),
- 'python': ('https://docs.python.org/3/', None),
- 'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None),
- 'statsmodels': ('http://www.statsmodels.org/devel/', None),
- }
- # extlinks alias
- extlinks = {'issue': ('https://github.com/pandas-dev/pandas/issues/%s',
- 'GH'),
- 'wiki': ('https://github.com/pandas-dev/pandas/wiki/%s',
- 'wiki ')}
- # ignore all deprecation warnings from Panel during doc build
- # (to avoid the need to add :okwarning: in many places)
- warnings.filterwarnings("ignore", message="\nPanel is deprecated",
- category=FutureWarning)
- ipython_warning_is_error = False
- ipython_exec_lines = [
- 'import numpy as np',
- 'import pandas as pd',
- # This ensures correct rendering on system with console encoding != utf8
- # (windows). It forces pandas to encode its output reprs using utf8
- # wherever the docs are built. The docs' target is the browser, not
- # the console, so this is fine.
- 'pd.options.display.encoding="utf8"'
- ]
- def sphinxdocstring_str(self, indent=0, func_role="obj"):
- # Pandas displays Attributes section in style like Methods section
- # Function is copy of `SphinxDocString.__str__`
- ns = {
- 'signature': self._str_signature(),
- 'index': self._str_index(),
- 'summary': self._str_summary(),
- 'extended_summary': self._str_extended_summary(),
- 'parameters': self._str_param_list('Parameters'),
- 'returns': self._str_returns('Returns'),
- 'yields': self._str_returns('Yields'),
- 'other_parameters': self._str_param_list('Other Parameters'),
- 'raises': self._str_param_list('Raises'),
- 'warns': self._str_param_list('Warns'),
- 'warnings': self._str_warnings(),
- 'see_also': self._str_see_also(func_role),
- 'notes': self._str_section('Notes'),
- 'references': self._str_references(),
- 'examples': self._str_examples(),
- # Replaced `self._str_param_list('Attributes', fake_autosummary=True)`
- # with `self._str_member_list('Attributes')`
- 'attributes': self._str_member_list('Attributes'),
- 'methods': self._str_member_list('Methods'),
- }
- ns = {k: '\n'.join(v) for k, v in ns.items()}
- rendered = self.template.render(**ns)
- return '\n'.join(self._str_indent(rendered.split('\n'), indent))
- SphinxDocString.__str__ = sphinxdocstring_str
- # Fix "WARNING: Inline strong start-string without end-string."
- # PR #155 "Escape the * in *args and **kwargs" from numpydoc
- # Can be removed after PR merges in v0.9.0
- def decorate_process_param(func):
- def _escape_args_and_kwargs(name):
- if name[:2] == '**':
- return r'\*\*' + name[2:]
- elif name[:1] == '*':
- return r'\*' + name[1:]
- else:
- return name
- def func_wrapper(self, param, desc, fake_autosummary):
- param = _escape_args_and_kwargs(param.strip())
- return func(self, param, desc, fake_autosummary)
- return func_wrapper
- func = SphinxDocString._process_param
- SphinxDocString._process_param = decorate_process_param(func)
- # Add custom Documenter to handle attributes/methods of an AccessorProperty
- # eg pandas.Series.str and pandas.Series.dt (see GH9322)
- import sphinx
- from sphinx.util import rpartition
- from sphinx.ext.autodoc import (
- Documenter, MethodDocumenter, AttributeDocumenter)
- from sphinx.ext.autosummary import Autosummary
- 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__')
- class PandasAutosummary(Autosummary):
- """
- This alternative autosummary class lets us override the table summary for
- Series.plot and DataFrame.plot in the API docs.
- """
- def _replace_pandas_items(self, display_name, sig, summary, real_name):
- # this a hack: ideally we should extract the signature from the
- # .__call__ method instead of hard coding this
- if display_name == 'DataFrame.plot':
- sig = '([x, y, kind, ax, ....])'
- summary = 'DataFrame plotting accessor and method'
- elif display_name == 'Series.plot':
- sig = '([kind, ax, figsize, ....])'
- summary = 'Series plotting accessor and method'
- return (display_name, sig, summary, real_name)
- @staticmethod
- def _is_deprecated(real_name):
- try:
- obj, parent, modname = _import_by_name(real_name)
- except ImportError:
- return False
- doc = NumpyDocString(obj.__doc__ or '')
- summary = ''.join(doc['Summary'] + doc['Extended Summary'])
- return '.. deprecated::' in summary
- def _add_deprecation_prefixes(self, items):
- for item in items:
- display_name, sig, summary, real_name = item
- if self._is_deprecated(real_name):
- summary = '(DEPRECATED) %s' % summary
- yield display_name, sig, summary, real_name
- def get_items(self, names):
- items = Autosummary.get_items(self, names)
- items = [self._replace_pandas_items(*item) for item in items]
- items = list(self._add_deprecation_prefixes(items))
- return items
- # based on numpy doc/source/conf.py
- def linkcode_resolve(domain, info):
- """
- Determine the URL corresponding to Python object
- """
- if domain != 'py':
- return None
- modname = info['module']
- fullname = info['fullname']
- submod = sys.modules.get(modname)
- if submod is None:
- return None
- obj = submod
- for part in fullname.split('.'):
- try:
- obj = getattr(obj, part)
- except AttributeError:
- return None
- try:
- # inspect.unwrap() was added in Python version 3.4
- if sys.version_info >= (3, 5):
- fn = inspect.getsourcefile(inspect.unwrap(obj))
- else:
- fn = inspect.getsourcefile(obj)
- except TypeError:
- fn = None
- if not fn:
- return None
- try:
- source, lineno = inspect.getsourcelines(obj)
- except OSError:
- lineno = None
- if lineno:
- linespec = "#L{:d}-L{:d}".format(lineno, lineno + len(source) - 1)
- else:
- linespec = ""
- fn = os.path.relpath(fn, start=os.path.dirname(pandas.__file__))
- if '+' in pandas.__version__:
- return ("http://github.com/pandas-dev/pandas/blob/master/pandas/"
- "{}{}".format(fn, linespec))
- else:
- return ("http://github.com/pandas-dev/pandas/blob/"
- "v{}/pandas/{}{}".format(pandas.__version__, fn, linespec))
- # remove the docstring of the flags attribute (inherited from numpy ndarray)
- # because these give doc build errors (see GH issue 5331)
- def remove_flags_docstring(app, what, name, obj, options, lines):
- if what == "attribute" and name.endswith(".flags"):
- del lines[:]
- def process_class_docstrings(app, what, name, obj, options, lines):
- """
- For those classes for which we use ::
- :template: autosummary/class_without_autosummary.rst
- the documented attributes/methods have to be listed in the class
- docstring. However, if one of those lists is empty, we use 'None',
- which then generates warnings in sphinx / ugly html output.
- This "autodoc-process-docstring" event connector removes that part
- from the processed docstring.
- """
- if what == "class":
- joined = '\n'.join(lines)
- templates = [
- """.. rubric:: Attributes
- .. autosummary::
- :toctree:
- None
- """,
- """.. rubric:: Methods
- .. autosummary::
- :toctree:
- None
- """
- ]
- for template in templates:
- if template in joined:
- joined = joined.replace(template, '')
- lines[:] = joined.split('\n')
- suppress_warnings = [
- # We "overwrite" autosummary with our PandasAutosummary, but
- # still want the regular autosummary setup to run. So we just
- # suppress this warning.
- 'app.add_directive'
- ]
- if pattern:
- # When building a single document we don't want to warn because references
- # to other documents are unknown, as it's expected
- suppress_warnings.append('ref.ref')
- def rstjinja(app, docname, source):
- """
- Render our pages as a jinja template for fancy templating goodness.
- """
- # http://ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/
- # Make sure we're outputting HTML
- if app.builder.format != 'html':
- return
- src = source[0]
- rendered = app.builder.templates.render_string(
- src, app.config.html_context
- )
- source[0] = rendered
- def setup(app):
- app.connect("source-read", rstjinja)
- app.connect("autodoc-process-docstring", remove_flags_docstring)
- app.connect("autodoc-process-docstring", process_class_docstrings)
- app.add_autodocumenter(AccessorDocumenter)
- app.add_autodocumenter(AccessorAttributeDocumenter)
- app.add_autodocumenter(AccessorMethodDocumenter)
- app.add_autodocumenter(AccessorCallableDocumenter)
- app.add_directive('autosummary', PandasAutosummary)