Fix code style issues with Black
This commit is contained in:
229
docs/conf.py
229
docs/conf.py
@ -18,45 +18,45 @@ import re
|
||||
# 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.insert(0, os.path.abspath('..'))
|
||||
sys.path.append(os.path.abspath('extensions'))
|
||||
sys.path.insert(0, os.path.abspath(".."))
|
||||
sys.path.append(os.path.abspath("extensions"))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'builder',
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.extlinks',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.napoleon',
|
||||
'sphinxcontrib_trio',
|
||||
'details',
|
||||
'exception_hierarchy',
|
||||
'attributetable',
|
||||
'resourcelinks',
|
||||
'nitpick_file_ignorer',
|
||||
"builder",
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.extlinks",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinxcontrib_trio",
|
||||
"details",
|
||||
"exception_hierarchy",
|
||||
"attributetable",
|
||||
"resourcelinks",
|
||||
"nitpick_file_ignorer",
|
||||
]
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_typehints = 'none'
|
||||
autodoc_member_order = "bysource"
|
||||
autodoc_typehints = "none"
|
||||
# maybe consider this?
|
||||
# napoleon_attr_annotations = False
|
||||
|
||||
extlinks = {
|
||||
'issue': ('https://github.com/Rapptz/discord.py/issues/%s', 'GH-'),
|
||||
"issue": ("https://github.com/Rapptz/discord.py/issues/%s", "GH-"),
|
||||
}
|
||||
|
||||
# Links used for cross-referencing stuff in other documentation
|
||||
intersphinx_mapping = {
|
||||
'py': ('https://docs.python.org/3', None),
|
||||
'aio': ('https://docs.aiohttp.org/en/stable/', None),
|
||||
'req': ('https://docs.python-requests.org/en/latest/', None)
|
||||
"py": ("https://docs.python.org/3", None),
|
||||
"aio": ("https://docs.aiohttp.org/en/stable/", None),
|
||||
"req": ("https://docs.python-requests.org/en/latest/", None),
|
||||
}
|
||||
|
||||
rst_prolog = """
|
||||
@ -67,20 +67,20 @@ rst_prolog = """
|
||||
"""
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = 'discord.py'
|
||||
copyright = '2015-present, Rapptz'
|
||||
project = "discord.py"
|
||||
copyright = "2015-present, Rapptz"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@ -88,15 +88,15 @@ copyright = '2015-present, Rapptz'
|
||||
#
|
||||
# The short X.Y version.
|
||||
|
||||
version = ''
|
||||
with open('../discord/__init__.py') as f:
|
||||
version = ""
|
||||
with open("../discord/__init__.py") as f:
|
||||
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1)
|
||||
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
# This assumes a tag is available for final releases
|
||||
branch = 'master' if version.endswith('a') else 'v' + version
|
||||
branch = "master" if version.endswith("a") else "v" + version
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@ -105,49 +105,49 @@ branch = 'master' if version.endswith('a') else 'v' + version
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
locale_dirs = ['locale/']
|
||||
locale_dirs = ["locale/"]
|
||||
gettext_compact = False
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
exclude_patterns = ["_build"]
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
# 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
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'friendly'
|
||||
pygments_style = "friendly"
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
# modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
# keep_warnings = False
|
||||
|
||||
|
||||
# Nitpicky mode options
|
||||
nitpick_ignore_files = [
|
||||
"migrating_to_async",
|
||||
"migrating",
|
||||
"whats_new",
|
||||
"migrating_to_async",
|
||||
"migrating",
|
||||
"whats_new",
|
||||
]
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
@ -156,21 +156,21 @@ html_experimental_html5_writer = True
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'basic'
|
||||
html_theme = "basic"
|
||||
|
||||
html_context = {
|
||||
'discord_invite': 'https://discord.gg/r3sSKJJ',
|
||||
'discord_extensions': [
|
||||
('discord.ext.commands', 'ext/commands'),
|
||||
('discord.ext.tasks', 'ext/tasks'),
|
||||
],
|
||||
"discord_invite": "https://discord.gg/r3sSKJJ",
|
||||
"discord_extensions": [
|
||||
("discord.ext.commands", "ext/commands"),
|
||||
("discord.ext.tasks", "ext/tasks"),
|
||||
],
|
||||
}
|
||||
|
||||
resource_links = {
|
||||
'discord': 'https://discord.gg/r3sSKJJ',
|
||||
'issues': 'https://github.com/Rapptz/discord.py/issues',
|
||||
'discussions': 'https://github.com/Rapptz/discord.py/discussions',
|
||||
'examples': f'https://github.com/Rapptz/discord.py/tree/{branch}/examples',
|
||||
"discord": "https://discord.gg/r3sSKJJ",
|
||||
"issues": "https://github.com/Rapptz/discord.py/issues",
|
||||
"discussions": "https://github.com/Rapptz/discord.py/discussions",
|
||||
"examples": f"https://github.com/Rapptz/discord.py/tree/{branch}/examples",
|
||||
}
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
@ -180,155 +180,143 @@ resource_links = {
|
||||
# }
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
# 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
|
||||
# html_logo = None
|
||||
|
||||
# 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 = './images/discord_py_logo.ico'
|
||||
html_favicon = "./images/discord_py_logo.ico"
|
||||
|
||||
# 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']
|
||||
html_static_path = ["_static"]
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
# html_extra_path = []
|
||||
|
||||
# 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'
|
||||
# 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
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
# html_show_copyright = 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 = ''
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
# html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
||||
#html_search_language = 'en'
|
||||
# html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
#html_search_options = {'type': 'default'}
|
||||
# html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
html_search_scorer = '_static/scorer.js'
|
||||
html_search_scorer = "_static/scorer.js"
|
||||
|
||||
html_js_files = [
|
||||
'custom.js',
|
||||
'settings.js',
|
||||
'copy.js',
|
||||
'sidebar.js'
|
||||
]
|
||||
html_js_files = ["custom.js", "settings.js", "copy.js", "sidebar.js"]
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'discord.pydoc'
|
||||
htmlhelp_basename = "discord.pydoc"
|
||||
|
||||
# -- 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 figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
# 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 figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'discord.py.tex', 'discord.py Documentation',
|
||||
'Rapptz', 'manual'),
|
||||
("index", "discord.py.tex", "discord.py Documentation", "Rapptz", "manual"),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'discord.py', 'discord.py Documentation',
|
||||
['Rapptz'], 1)
|
||||
]
|
||||
man_pages = [("index", "discord.py", "discord.py Documentation", ["Rapptz"], 1)]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
@ -337,25 +325,32 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'discord.py', 'discord.py Documentation',
|
||||
'Rapptz', 'discord.py', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
(
|
||||
"index",
|
||||
"discord.py",
|
||||
"discord.py Documentation",
|
||||
"Rapptz",
|
||||
"discord.py",
|
||||
"One line description of project.",
|
||||
"Miscellaneous",
|
||||
),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
# texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
def setup(app):
|
||||
if app.config.language == 'ja':
|
||||
app.config.intersphinx_mapping['py'] = ('https://docs.python.org/ja/3', None)
|
||||
app.config.html_context['discord_invite'] = 'https://discord.gg/nXzj3dg'
|
||||
app.config.resource_links['discord'] = 'https://discord.gg/nXzj3dg'
|
||||
if app.config.language == "ja":
|
||||
app.config.intersphinx_mapping["py"] = ("https://docs.python.org/ja/3", None)
|
||||
app.config.html_context["discord_invite"] = "https://discord.gg/nXzj3dg"
|
||||
app.config.resource_links["discord"] = "https://discord.gg/nXzj3dg"
|
||||
|
@ -9,60 +9,78 @@ import inspect
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
class attributetable(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
class attributetablecolumn(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
class attributetabletitle(nodes.TextElement):
|
||||
pass
|
||||
|
||||
|
||||
class attributetableplaceholder(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
class attributetablebadge(nodes.TextElement):
|
||||
pass
|
||||
|
||||
|
||||
class attributetable_item(nodes.Part, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
def visit_attributetable_node(self, node):
|
||||
class_ = node["python-class"]
|
||||
self.body.append(f'<div class="py-attribute-table" data-move-to-id="{class_}">')
|
||||
|
||||
|
||||
def visit_attributetablecolumn_node(self, node):
|
||||
self.body.append(self.starttag(node, 'div', CLASS='py-attribute-table-column'))
|
||||
self.body.append(self.starttag(node, "div", CLASS="py-attribute-table-column"))
|
||||
|
||||
|
||||
def visit_attributetabletitle_node(self, node):
|
||||
self.body.append(self.starttag(node, 'span'))
|
||||
self.body.append(self.starttag(node, "span"))
|
||||
|
||||
|
||||
def visit_attributetablebadge_node(self, node):
|
||||
attributes = {
|
||||
'class': 'py-attribute-table-badge',
|
||||
'title': node['badge-type'],
|
||||
"class": "py-attribute-table-badge",
|
||||
"title": node["badge-type"],
|
||||
}
|
||||
self.body.append(self.starttag(node, 'span', **attributes))
|
||||
self.body.append(self.starttag(node, "span", **attributes))
|
||||
|
||||
|
||||
def visit_attributetable_item_node(self, node):
|
||||
self.body.append(self.starttag(node, 'li', CLASS='py-attribute-table-entry'))
|
||||
self.body.append(self.starttag(node, "li", CLASS="py-attribute-table-entry"))
|
||||
|
||||
|
||||
def depart_attributetable_node(self, node):
|
||||
self.body.append('</div>')
|
||||
self.body.append("</div>")
|
||||
|
||||
|
||||
def depart_attributetablecolumn_node(self, node):
|
||||
self.body.append('</div>')
|
||||
self.body.append("</div>")
|
||||
|
||||
|
||||
def depart_attributetabletitle_node(self, node):
|
||||
self.body.append('</span>')
|
||||
self.body.append("</span>")
|
||||
|
||||
|
||||
def depart_attributetablebadge_node(self, node):
|
||||
self.body.append('</span>')
|
||||
self.body.append("</span>")
|
||||
|
||||
|
||||
def depart_attributetable_item_node(self, node):
|
||||
self.body.append('</li>')
|
||||
self.body.append("</li>")
|
||||
|
||||
|
||||
_name_parser_regex = re.compile(r"(?P<module>[\w.]+\.)?(?P<name>\w+)")
|
||||
|
||||
_name_parser_regex = re.compile(r'(?P<module>[\w.]+\.)?(?P<name>\w+)')
|
||||
|
||||
class PyAttributeTable(SphinxDirective):
|
||||
has_content = False
|
||||
@ -74,13 +92,13 @@ class PyAttributeTable(SphinxDirective):
|
||||
def parse_name(self, content):
|
||||
path, name = _name_parser_regex.match(content).groups()
|
||||
if path:
|
||||
modulename = path.rstrip('.')
|
||||
modulename = path.rstrip(".")
|
||||
else:
|
||||
modulename = self.env.temp_data.get('autodoc:module')
|
||||
modulename = self.env.temp_data.get("autodoc:module")
|
||||
if not modulename:
|
||||
modulename = self.env.ref_context.get('py:module')
|
||||
modulename = self.env.ref_context.get("py:module")
|
||||
if modulename is None:
|
||||
raise RuntimeError('modulename somehow None for %s in %s.' % (content, self.env.docname))
|
||||
raise RuntimeError("modulename somehow None for %s in %s." % (content, self.env.docname))
|
||||
|
||||
return modulename, name
|
||||
|
||||
@ -112,29 +130,33 @@ class PyAttributeTable(SphinxDirective):
|
||||
replaced.
|
||||
"""
|
||||
content = self.arguments[0].strip()
|
||||
node = attributetableplaceholder('')
|
||||
node = attributetableplaceholder("")
|
||||
modulename, name = self.parse_name(content)
|
||||
node['python-doc'] = self.env.docname
|
||||
node['python-module'] = modulename
|
||||
node['python-class'] = name
|
||||
node['python-full-name'] = f'{modulename}.{name}'
|
||||
node["python-doc"] = self.env.docname
|
||||
node["python-module"] = modulename
|
||||
node["python-class"] = name
|
||||
node["python-full-name"] = f"{modulename}.{name}"
|
||||
return [node]
|
||||
|
||||
|
||||
def build_lookup_table(env):
|
||||
# Given an environment, load up a lookup table of
|
||||
# full-class-name: objects
|
||||
result = {}
|
||||
domain = env.domains['py']
|
||||
domain = env.domains["py"]
|
||||
|
||||
ignored = {
|
||||
'data', 'exception', 'module', 'class',
|
||||
"data",
|
||||
"exception",
|
||||
"module",
|
||||
"class",
|
||||
}
|
||||
|
||||
for (fullname, _, objtype, docname, _, _) in domain.get_objects():
|
||||
if objtype in ignored:
|
||||
continue
|
||||
|
||||
classname, _, child = fullname.rpartition('.')
|
||||
classname, _, child = fullname.rpartition(".")
|
||||
try:
|
||||
result[classname].append(child)
|
||||
except KeyError:
|
||||
@ -143,36 +165,40 @@ def build_lookup_table(env):
|
||||
return result
|
||||
|
||||
|
||||
TableElement = namedtuple('TableElement', 'fullname label badge')
|
||||
TableElement = namedtuple("TableElement", "fullname label badge")
|
||||
|
||||
|
||||
def process_attributetable(app, doctree, fromdocname):
|
||||
env = app.builder.env
|
||||
|
||||
lookup = build_lookup_table(env)
|
||||
for node in doctree.traverse(attributetableplaceholder):
|
||||
modulename, classname, fullname = node['python-module'], node['python-class'], node['python-full-name']
|
||||
modulename, classname, fullname = node["python-module"], node["python-class"], node["python-full-name"]
|
||||
groups = get_class_results(lookup, modulename, classname, fullname)
|
||||
table = attributetable('')
|
||||
table = attributetable("")
|
||||
for label, subitems in groups.items():
|
||||
if not subitems:
|
||||
continue
|
||||
table.append(class_results_to_node(label, sorted(subitems, key=lambda c: c.label)))
|
||||
|
||||
table['python-class'] = fullname
|
||||
table["python-class"] = fullname
|
||||
|
||||
if not table:
|
||||
node.replace_self([])
|
||||
else:
|
||||
node.replace_self([table])
|
||||
|
||||
|
||||
def get_class_results(lookup, modulename, name, fullname):
|
||||
module = importlib.import_module(modulename)
|
||||
cls = getattr(module, name)
|
||||
|
||||
groups = OrderedDict([
|
||||
(_('Attributes'), []),
|
||||
(_('Methods'), []),
|
||||
])
|
||||
groups = OrderedDict(
|
||||
[
|
||||
(_("Attributes"), []),
|
||||
(_("Methods"), []),
|
||||
]
|
||||
)
|
||||
|
||||
try:
|
||||
members = lookup[fullname]
|
||||
@ -180,8 +206,8 @@ def get_class_results(lookup, modulename, name, fullname):
|
||||
return groups
|
||||
|
||||
for attr in members:
|
||||
attrlookup = f'{fullname}.{attr}'
|
||||
key = _('Attributes')
|
||||
attrlookup = f"{fullname}.{attr}"
|
||||
key = _("Attributes")
|
||||
badge = None
|
||||
label = attr
|
||||
value = None
|
||||
@ -192,53 +218,54 @@ def get_class_results(lookup, modulename, name, fullname):
|
||||
break
|
||||
|
||||
if value is not None:
|
||||
doc = value.__doc__ or ''
|
||||
if inspect.iscoroutinefunction(value) or doc.startswith('|coro|'):
|
||||
key = _('Methods')
|
||||
badge = attributetablebadge('async', 'async')
|
||||
badge['badge-type'] = _('coroutine')
|
||||
doc = value.__doc__ or ""
|
||||
if inspect.iscoroutinefunction(value) or doc.startswith("|coro|"):
|
||||
key = _("Methods")
|
||||
badge = attributetablebadge("async", "async")
|
||||
badge["badge-type"] = _("coroutine")
|
||||
elif isinstance(value, classmethod):
|
||||
key = _('Methods')
|
||||
label = f'{name}.{attr}'
|
||||
badge = attributetablebadge('cls', 'cls')
|
||||
badge['badge-type'] = _('classmethod')
|
||||
key = _("Methods")
|
||||
label = f"{name}.{attr}"
|
||||
badge = attributetablebadge("cls", "cls")
|
||||
badge["badge-type"] = _("classmethod")
|
||||
elif inspect.isfunction(value):
|
||||
if doc.startswith(('A decorator', 'A shortcut decorator')):
|
||||
if doc.startswith(("A decorator", "A shortcut decorator")):
|
||||
# finicky but surprisingly consistent
|
||||
badge = attributetablebadge('@', '@')
|
||||
badge['badge-type'] = _('decorator')
|
||||
key = _('Methods')
|
||||
badge = attributetablebadge("@", "@")
|
||||
badge["badge-type"] = _("decorator")
|
||||
key = _("Methods")
|
||||
else:
|
||||
key = _('Methods')
|
||||
badge = attributetablebadge('def', 'def')
|
||||
badge['badge-type'] = _('method')
|
||||
key = _("Methods")
|
||||
badge = attributetablebadge("def", "def")
|
||||
badge["badge-type"] = _("method")
|
||||
|
||||
groups[key].append(TableElement(fullname=attrlookup, label=label, badge=badge))
|
||||
|
||||
return groups
|
||||
|
||||
|
||||
def class_results_to_node(key, elements):
|
||||
title = attributetabletitle(key, key)
|
||||
ul = nodes.bullet_list('')
|
||||
ul = nodes.bullet_list("")
|
||||
for element in elements:
|
||||
ref = nodes.reference('', '', internal=True,
|
||||
refuri='#' + element.fullname,
|
||||
anchorname='',
|
||||
*[nodes.Text(element.label)])
|
||||
para = addnodes.compact_paragraph('', '', ref)
|
||||
ref = nodes.reference(
|
||||
"", "", internal=True, refuri="#" + element.fullname, anchorname="", *[nodes.Text(element.label)]
|
||||
)
|
||||
para = addnodes.compact_paragraph("", "", ref)
|
||||
if element.badge is not None:
|
||||
ul.append(attributetable_item('', element.badge, para))
|
||||
ul.append(attributetable_item("", element.badge, para))
|
||||
else:
|
||||
ul.append(attributetable_item('', para))
|
||||
ul.append(attributetable_item("", para))
|
||||
|
||||
return attributetablecolumn("", title, ul)
|
||||
|
||||
return attributetablecolumn('', title, ul)
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('attributetable', PyAttributeTable)
|
||||
app.add_directive("attributetable", PyAttributeTable)
|
||||
app.add_node(attributetable, html=(visit_attributetable_node, depart_attributetable_node))
|
||||
app.add_node(attributetablecolumn, html=(visit_attributetablecolumn_node, depart_attributetablecolumn_node))
|
||||
app.add_node(attributetabletitle, html=(visit_attributetabletitle_node, depart_attributetabletitle_node))
|
||||
app.add_node(attributetablebadge, html=(visit_attributetablebadge_node, depart_attributetablebadge_node))
|
||||
app.add_node(attributetable_item, html=(visit_attributetable_item_node, depart_attributetable_item_node))
|
||||
app.add_node(attributetableplaceholder)
|
||||
app.connect('doctree-resolved', process_attributetable)
|
||||
app.connect("doctree-resolved", process_attributetable)
|
||||
|
@ -2,15 +2,15 @@ from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.environment.adapters.indexentries import IndexEntries
|
||||
from sphinx.writers.html5 import HTML5Translator
|
||||
|
||||
|
||||
class DPYHTML5Translator(HTML5Translator):
|
||||
def visit_section(self, node):
|
||||
self.section_level += 1
|
||||
self.body.append(
|
||||
self.starttag(node, 'section'))
|
||||
self.body.append(self.starttag(node, "section"))
|
||||
|
||||
def depart_section(self, node):
|
||||
self.section_level -= 1
|
||||
self.body.append('</section>\n')
|
||||
self.body.append("</section>\n")
|
||||
|
||||
def visit_table(self, node):
|
||||
self.body.append('<div class="table-wrapper">')
|
||||
@ -18,7 +18,8 @@ class DPYHTML5Translator(HTML5Translator):
|
||||
|
||||
def depart_table(self, node):
|
||||
super().depart_table(node)
|
||||
self.body.append('</div>')
|
||||
self.body.append("</div>")
|
||||
|
||||
|
||||
class DPYStandaloneHTMLBuilder(StandaloneHTMLBuilder):
|
||||
# This is mostly copy pasted from Sphinx.
|
||||
@ -28,50 +29,48 @@ class DPYStandaloneHTMLBuilder(StandaloneHTMLBuilder):
|
||||
genindex = IndexEntries(self.env).create_index(self, group_entries=False)
|
||||
indexcounts = []
|
||||
for _k, entries in genindex:
|
||||
indexcounts.append(sum(1 + len(subitems)
|
||||
for _, (_, subitems, _) in entries))
|
||||
indexcounts.append(sum(1 + len(subitems) for _, (_, subitems, _) in entries))
|
||||
|
||||
genindexcontext = {
|
||||
'genindexentries': genindex,
|
||||
'genindexcounts': indexcounts,
|
||||
'split_index': self.config.html_split_index,
|
||||
"genindexentries": genindex,
|
||||
"genindexcounts": indexcounts,
|
||||
"split_index": self.config.html_split_index,
|
||||
}
|
||||
|
||||
if self.config.html_split_index:
|
||||
self.handle_page('genindex', genindexcontext,
|
||||
'genindex-split.html')
|
||||
self.handle_page('genindex-all', genindexcontext,
|
||||
'genindex.html')
|
||||
self.handle_page("genindex", genindexcontext, "genindex-split.html")
|
||||
self.handle_page("genindex-all", genindexcontext, "genindex.html")
|
||||
for (key, entries), count in zip(genindex, indexcounts):
|
||||
ctx = {'key': key, 'entries': entries, 'count': count,
|
||||
'genindexentries': genindex}
|
||||
self.handle_page('genindex-' + key, ctx,
|
||||
'genindex-single.html')
|
||||
ctx = {"key": key, "entries": entries, "count": count, "genindexentries": genindex}
|
||||
self.handle_page("genindex-" + key, ctx, "genindex-single.html")
|
||||
else:
|
||||
self.handle_page('genindex', genindexcontext, 'genindex.html')
|
||||
self.handle_page("genindex", genindexcontext, "genindex.html")
|
||||
|
||||
|
||||
def add_custom_jinja2(app):
|
||||
env = app.builder.templates.environment
|
||||
env.tests['prefixedwith'] = str.startswith
|
||||
env.tests['suffixedwith'] = str.endswith
|
||||
env.tests["prefixedwith"] = str.startswith
|
||||
env.tests["suffixedwith"] = str.endswith
|
||||
|
||||
|
||||
def add_builders(app):
|
||||
"""This is necessary because RTD injects their own for some reason."""
|
||||
app.set_translator('html', DPYHTML5Translator, override=True)
|
||||
app.set_translator("html", DPYHTML5Translator, override=True)
|
||||
app.add_builder(DPYStandaloneHTMLBuilder, override=True)
|
||||
|
||||
try:
|
||||
original = app.registry.builders['readthedocs']
|
||||
original = app.registry.builders["readthedocs"]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
injected_mro = tuple(base if base is not StandaloneHTMLBuilder else DPYStandaloneHTMLBuilder
|
||||
for base in original.mro()[1:])
|
||||
new_builder = type(original.__name__, injected_mro, {'name': 'readthedocs'})
|
||||
app.set_translator('readthedocs', DPYHTML5Translator, override=True)
|
||||
injected_mro = tuple(
|
||||
base if base is not StandaloneHTMLBuilder else DPYStandaloneHTMLBuilder for base in original.mro()[1:]
|
||||
)
|
||||
new_builder = type(original.__name__, injected_mro, {"name": "readthedocs"})
|
||||
app.set_translator("readthedocs", DPYHTML5Translator, override=True)
|
||||
app.add_builder(new_builder, override=True)
|
||||
|
||||
|
||||
def setup(app):
|
||||
add_builders(app)
|
||||
app.connect('builder-inited', add_custom_jinja2)
|
||||
app.connect("builder-inited", add_custom_jinja2)
|
||||
|
@ -3,32 +3,39 @@ from docutils.parsers.rst import states, directives
|
||||
from docutils.parsers.rst.roles import set_classes
|
||||
from docutils import nodes
|
||||
|
||||
|
||||
class details(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
class summary(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
def visit_details_node(self, node):
|
||||
self.body.append(self.starttag(node, 'details', CLASS=node.attributes.get('class', '')))
|
||||
self.body.append(self.starttag(node, "details", CLASS=node.attributes.get("class", "")))
|
||||
|
||||
|
||||
def visit_summary_node(self, node):
|
||||
self.body.append(self.starttag(node, 'summary', CLASS=node.attributes.get('summary-class', '')))
|
||||
self.body.append(self.starttag(node, "summary", CLASS=node.attributes.get("summary-class", "")))
|
||||
self.body.append(node.rawsource)
|
||||
|
||||
|
||||
def depart_details_node(self, node):
|
||||
self.body.append('</details>\n')
|
||||
self.body.append("</details>\n")
|
||||
|
||||
|
||||
def depart_summary_node(self, node):
|
||||
self.body.append('</summary>')
|
||||
self.body.append("</summary>")
|
||||
|
||||
|
||||
class DetailsDirective(Directive):
|
||||
final_argument_whitespace = True
|
||||
optional_arguments = 1
|
||||
|
||||
option_spec = {
|
||||
'class': directives.class_option,
|
||||
'summary-class': directives.class_option,
|
||||
"class": directives.class_option,
|
||||
"summary-class": directives.class_option,
|
||||
}
|
||||
|
||||
has_content = True
|
||||
@ -37,7 +44,7 @@ class DetailsDirective(Directive):
|
||||
set_classes(self.options)
|
||||
self.assert_has_content()
|
||||
|
||||
text = '\n'.join(self.content)
|
||||
text = "\n".join(self.content)
|
||||
node = details(text, **self.options)
|
||||
|
||||
if self.arguments:
|
||||
@ -48,8 +55,8 @@ class DetailsDirective(Directive):
|
||||
self.state.nested_parse(self.content, self.content_offset, node)
|
||||
return [node]
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_node(details, html=(visit_details_node, depart_details_node))
|
||||
app.add_node(summary, html=(visit_summary_node, depart_summary_node))
|
||||
app.add_directive('details', DetailsDirective)
|
||||
|
||||
app.add_directive("details", DetailsDirective)
|
||||
|
@ -4,24 +4,29 @@ from docutils.parsers.rst.roles import set_classes
|
||||
from docutils import nodes
|
||||
from sphinx.locale import _
|
||||
|
||||
|
||||
class exception_hierarchy(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
def visit_exception_hierarchy_node(self, node):
|
||||
self.body.append(self.starttag(node, 'div', CLASS='exception-hierarchy-content'))
|
||||
self.body.append(self.starttag(node, "div", CLASS="exception-hierarchy-content"))
|
||||
|
||||
|
||||
def depart_exception_hierarchy_node(self, node):
|
||||
self.body.append('</div>\n')
|
||||
self.body.append("</div>\n")
|
||||
|
||||
|
||||
class ExceptionHierarchyDirective(Directive):
|
||||
has_content = True
|
||||
|
||||
def run(self):
|
||||
self.assert_has_content()
|
||||
node = exception_hierarchy('\n'.join(self.content))
|
||||
node = exception_hierarchy("\n".join(self.content))
|
||||
self.state.nested_parse(self.content, self.content_offset, node)
|
||||
return [node]
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_node(exception_hierarchy, html=(visit_exception_hierarchy_node, depart_exception_hierarchy_node))
|
||||
app.add_directive('exception_hierarchy', ExceptionHierarchyDirective)
|
||||
app.add_directive("exception_hierarchy", ExceptionHierarchyDirective)
|
||||
|
@ -5,18 +5,17 @@ from sphinx.util import logging as sphinx_logging
|
||||
|
||||
|
||||
class NitpickFileIgnorer(logging.Filter):
|
||||
|
||||
def __init__(self, app: Sphinx) -> None:
|
||||
self.app = app
|
||||
super().__init__()
|
||||
|
||||
def filter(self, record: sphinx_logging.SphinxLogRecord) -> bool:
|
||||
if getattr(record, 'type', None) == 'ref':
|
||||
return record.location.get('refdoc') not in self.app.config.nitpick_ignore_files
|
||||
if getattr(record, "type", None) == "ref":
|
||||
return record.location.get("refdoc") not in self.app.config.nitpick_ignore_files
|
||||
return True
|
||||
|
||||
|
||||
def setup(app: Sphinx):
|
||||
app.add_config_value('nitpick_ignore_files', [], '')
|
||||
app.add_config_value("nitpick_ignore_files", [], "")
|
||||
f = NitpickFileIgnorer(app)
|
||||
sphinx_logging.getLogger('sphinx.transforms.post_transforms').logger.addFilter(f)
|
||||
sphinx_logging.getLogger("sphinx.transforms.post_transforms").logger.addFilter(f)
|
||||
|
@ -16,13 +16,7 @@ from sphinx.util.typing import RoleFunction
|
||||
|
||||
def make_link_role(resource_links: Dict[str, str]) -> RoleFunction:
|
||||
def role(
|
||||
typ: str,
|
||||
rawtext: str,
|
||||
text: str,
|
||||
lineno: int,
|
||||
inliner: Inliner,
|
||||
options: Dict = {},
|
||||
content: List[str] = []
|
||||
typ: str, rawtext: str, text: str, lineno: int, inliner: Inliner, options: Dict = {}, content: List[str] = []
|
||||
) -> Tuple[List[Node], List[system_message]]:
|
||||
|
||||
text = utils.unescape(text)
|
||||
@ -32,13 +26,15 @@ def make_link_role(resource_links: Dict[str, str]) -> RoleFunction:
|
||||
title = full_url
|
||||
pnode = nodes.reference(title, title, internal=False, refuri=full_url)
|
||||
return [pnode], []
|
||||
|
||||
return role
|
||||
|
||||
|
||||
def add_link_role(app: Sphinx) -> None:
|
||||
app.add_role('resource', make_link_role(app.config.resource_links))
|
||||
app.add_role("resource", make_link_role(app.config.resource_links))
|
||||
|
||||
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_config_value('resource_links', {}, 'env')
|
||||
app.connect('builder-inited', add_link_role)
|
||||
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
|
||||
app.add_config_value("resource_links", {}, "env")
|
||||
app.connect("builder-inited", add_link_role)
|
||||
return {"version": sphinx.__display_version__, "parallel_read_safe": True}
|
||||
|
Reference in New Issue
Block a user