diff --git a/.ruff.toml b/.ruff.toml index 60f4ad3b0..abf1951e3 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -423,9 +423,9 @@ forced-separate = [ ] [format] +preview = true quote-style = "single" exclude = [ - "doc/**/*", "sphinx/__init__.py", "sphinx/addnodes.py", "sphinx/application.py", diff --git a/doc/conf.py b/doc/conf.py index 2816935e6..493eb4ed5 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -8,11 +8,17 @@ import sphinx os.environ['SPHINX_AUTODOC_RELOAD_MODULES'] = '1' -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', - 'sphinx.ext.autosummary', 'sphinx.ext.extlinks', - 'sphinx.ext.intersphinx', - 'sphinx.ext.viewcode', 'sphinx.ext.inheritance_diagram', - 'sphinx.ext.coverage'] +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.todo', + 'sphinx.ext.autosummary', + 'sphinx.ext.extlinks', + 'sphinx.ext.intersphinx', + 'sphinx.ext.viewcode', + 'sphinx.ext.inheritance_diagram', + 'sphinx.ext.coverage', +] coverage_statistics_to_report = coverage_statistics_to_stdout = True templates_path = ['_templates'] exclude_patterns = ['_build'] @@ -49,40 +55,47 @@ epub_uid = 'web-site' epub_scheme = 'url' epub_identifier = epub_publisher epub_pre_files = [('index.xhtml', 'Welcome')] -epub_post_files = [('usage/installation.xhtml', 'Installing Sphinx'), - ('develop.xhtml', 'Sphinx development')] -epub_exclude_files = ['_static/opensearch.xml', '_static/doctools.js', - '_static/searchtools.js', - '_static/sphinx_highlight.js', - '_static/basic.css', - '_static/language_data.js', - 'search.html', '_static/websupport.js'] +epub_post_files = [ + ('usage/installation.xhtml', 'Installing Sphinx'), + ('develop.xhtml', 'Sphinx development'), +] +epub_exclude_files = [ + '_static/opensearch.xml', + '_static/doctools.js', + '_static/searchtools.js', + '_static/sphinx_highlight.js', + '_static/basic.css', + '_static/language_data.js', + 'search.html', + '_static/websupport.js', +] epub_fix_images = False epub_max_image_width = 0 epub_show_urls = 'inline' epub_use_index = False epub_description = 'Sphinx documentation generator system manual' -latex_documents = [('index', 'sphinx.tex', 'Sphinx Documentation', - 'the Sphinx developers', 'manual', 1)] +latex_documents = [ + ('index', 'sphinx.tex', 'Sphinx Documentation', 'the Sphinx developers', 'manual', 1) +] latex_logo = '_static/sphinx.png' latex_elements = { 'fontenc': r'\usepackage[LGR,X2,T1]{fontenc}', - 'passoptionstopackages': r''' + 'passoptionstopackages': r""" \PassOptionsToPackage{svgnames}{xcolor} -''', - 'preamble': r''' +""", + 'preamble': r""" \DeclareUnicodeCharacter{229E}{\ensuremath{\boxplus}} \setcounter{tocdepth}{3}% depth of what main TOC shows (3=subsubsection) \setcounter{secnumdepth}{1}% depth of section numbering \setlength{\tymin}{2cm}% avoid too cramped table columns -''', +""", # fix missing index entry due to RTD doing only once pdflatex after makeindex - 'printindex': r''' + 'printindex': r""" \IfFileExists{\jobname.ind} {\footnotesize\raggedright\printindex} {\begin{sphinxtheindex}\end{sphinxtheindex}} -''', +""", } latex_show_urls = 'footnote' latex_use_xindy = True @@ -92,30 +105,46 @@ linkcheck_timeout = 5 autodoc_member_order = 'groupwise' autosummary_generate = False todo_include_todos = True -extlinks = {'duref': ('https://docutils.sourceforge.io/docs/ref/rst/' - 'restructuredtext.html#%s', '%s'), - 'durole': ('https://docutils.sourceforge.io/docs/ref/rst/' - 'roles.html#%s', '%s'), - 'dudir': ('https://docutils.sourceforge.io/docs/ref/rst/' - 'directives.html#%s', '%s')} +extlinks = { + 'duref': ( + 'https://docutils.sourceforge.io/docs/ref/rst/' 'restructuredtext.html#%s', + '%s', + ), + 'durole': ('https://docutils.sourceforge.io/docs/ref/rst/' 'roles.html#%s', '%s'), + 'dudir': ('https://docutils.sourceforge.io/docs/ref/rst/' 'directives.html#%s', '%s'), +} man_pages = [ - ('index', 'sphinx-all', 'Sphinx documentation generator system manual', - 'the Sphinx developers', 1), - ('man/sphinx-build', 'sphinx-build', 'Sphinx documentation generator tool', - '', 1), - ('man/sphinx-quickstart', 'sphinx-quickstart', 'Sphinx documentation ' - 'template generator', '', 1), - ('man/sphinx-apidoc', 'sphinx-apidoc', 'Sphinx API doc generator tool', - '', 1), - ('man/sphinx-autogen', 'sphinx-autogen', 'Generate autodoc stub pages', - '', 1), + ( + 'index', + 'sphinx-all', + 'Sphinx documentation generator system manual', + 'the Sphinx developers', + 1, + ), + ('man/sphinx-build', 'sphinx-build', 'Sphinx documentation generator tool', '', 1), + ( + 'man/sphinx-quickstart', + 'sphinx-quickstart', + 'Sphinx documentation ' 'template generator', + '', + 1, + ), + ('man/sphinx-apidoc', 'sphinx-apidoc', 'Sphinx API doc generator tool', '', 1), + ('man/sphinx-autogen', 'sphinx-autogen', 'Generate autodoc stub pages', '', 1), ] texinfo_documents = [ - ('index', 'sphinx', 'Sphinx Documentation', 'the Sphinx developers', - 'Sphinx', 'The Sphinx documentation builder.', 'Documentation tools', - 1), + ( + 'index', + 'sphinx', + 'Sphinx Documentation', + 'the Sphinx developers', + 'Sphinx', + 'The Sphinx documentation builder.', + 'Documentation tools', + 1, + ), ] intersphinx_mapping = { @@ -129,7 +158,10 @@ locale_dirs = ['locale/'] gettext_compact = False nitpick_ignore = { - ('cpp:class', 'template template Wrapper::Outer::Inner'), # NoQA: E501 + ( + 'cpp:class', + 'template template Wrapper::Outer::Inner', + ), # NoQA: E501 ('cpp:identifier', 'MyContainer'), ('js:func', 'SomeError'), ('js:func', 'number'), @@ -213,13 +245,13 @@ def parse_event(env, sig, signode): def linkify_issues_in_changelog(app, docname, source): """Linkify issue references like #123 in changelog to GitHub.""" if docname == 'changes': - changelog_path = os.path.join(os.path.dirname(__file__), "../CHANGES.rst") + changelog_path = os.path.join(os.path.dirname(__file__), '../CHANGES.rst') # this path trickery is needed because this script can # be invoked with different working directories: # * running make in docs/ # * running tox -e docs in the repo root dir - with open(changelog_path, encoding="utf-8") as f: + with open(changelog_path, encoding='utf-8') as f: changelog = f.read() def linkify(match): @@ -234,12 +266,16 @@ def linkify_issues_in_changelog(app, docname, source): def setup(app): from sphinx.ext.autodoc import cut_lines from sphinx.util.docfields import GroupedField + app.connect('autodoc-process-docstring', cut_lines(4, what=['module'])) app.connect('source-read', linkify_issues_in_changelog) - app.add_object_type('confval', 'confval', - objname='configuration value', - indextemplate='pair: %s; configuration value') - fdesc = GroupedField('parameter', label='Parameters', - names=['param'], can_collapse=True) - app.add_object_type('event', 'event', 'pair: %s; event', parse_event, - doc_field_types=[fdesc]) + app.add_object_type( + 'confval', + 'confval', + objname='configuration value', + indextemplate='pair: %s; configuration value', + ) + fdesc = GroupedField('parameter', label='Parameters', names=['param'], can_collapse=True) + app.add_object_type( + 'event', 'event', 'pair: %s; event', parse_event, doc_field_types=[fdesc] + ) diff --git a/doc/development/tutorials/examples/autodoc_intenum.py b/doc/development/tutorials/examples/autodoc_intenum.py index 75fa20452..c52bb4cab 100644 --- a/doc/development/tutorials/examples/autodoc_intenum.py +++ b/doc/development/tutorials/examples/autodoc_intenum.py @@ -19,9 +19,9 @@ class IntEnumDocumenter(ClassDocumenter): option_spec['hex'] = bool_option @classmethod - def can_document_member(cls, - member: Any, membername: str, - isattr: bool, parent: Any) -> bool: + def can_document_member( + cls, member: Any, membername: str, isattr: bool, parent: Any + ) -> bool: try: return issubclass(member, IntEnum) except TypeError: @@ -31,11 +31,11 @@ class IntEnumDocumenter(ClassDocumenter): super().add_directive_header(sig) self.add_line(' :final:', self.get_sourcename()) - def add_content(self, - more_content: StringList | None, - no_docstring: bool = False, - ) -> None: - + def add_content( + self, + more_content: StringList | None, + no_docstring: bool = False, + ) -> None: super().add_content(more_content, no_docstring) source_name = self.get_sourcename() @@ -48,8 +48,7 @@ class IntEnumDocumenter(ClassDocumenter): if use_hex: the_member_value = hex(the_member_value) - self.add_line( - f"**{the_member_name}**: {the_member_value}", source_name) + self.add_line(f'**{the_member_name}**: {the_member_value}', source_name) self.add_line('', source_name) diff --git a/doc/development/tutorials/examples/helloworld.py b/doc/development/tutorials/examples/helloworld.py index d6d81fd4f..55ed1fd02 100644 --- a/doc/development/tutorials/examples/helloworld.py +++ b/doc/development/tutorials/examples/helloworld.py @@ -3,14 +3,13 @@ from docutils.parsers.rst import Directive class HelloWorld(Directive): - def run(self): paragraph_node = nodes.paragraph(text='Hello World!') return [paragraph_node] def setup(app): - app.add_directive("helloworld", HelloWorld) + app.add_directive('helloworld', HelloWorld) return { 'version': '0.1', diff --git a/doc/development/tutorials/examples/recipe.py b/doc/development/tutorials/examples/recipe.py index c7ebf2a93..18d948f9c 100644 --- a/doc/development/tutorials/examples/recipe.py +++ b/doc/development/tutorials/examples/recipe.py @@ -25,8 +25,7 @@ class RecipeDirective(ObjectDescription): def add_target_and_index(self, name_cls, sig, signode): signode['ids'].append('recipe' + '-' + sig) if 'contains' in self.options: - ingredients = [ - x.strip() for x in self.options.get('contains').split(',')] + ingredients = [x.strip() for x in self.options.get('contains').split(',')] recipes = self.env.get_domain('recipe') recipes.add_recipe(sig, ingredients) @@ -42,9 +41,10 @@ class IngredientIndex(Index): def generate(self, docnames=None): content = defaultdict(list) - recipes = {name: (dispname, typ, docname, anchor) - for name, dispname, typ, docname, anchor, _ - in self.domain.get_objects()} + recipes = { + name: (dispname, typ, docname, anchor) + for name, dispname, typ, docname, anchor, _ in self.domain.get_objects() + } recipe_ingredients = self.domain.data['recipe_ingredients'] ingredient_recipes = defaultdict(list) @@ -60,8 +60,7 @@ class IngredientIndex(Index): for ingredient, recipe_names in ingredient_recipes.items(): for recipe_name in recipe_names: dispname, typ, docname, anchor = recipes[recipe_name] - content[ingredient].append( - (dispname, 0, docname, anchor, docname, '', typ)) + content[ingredient].append((dispname, 0, docname, anchor, docname, '', typ)) # convert the dict to the sorted list of tuples expected content = sorted(content.items()) @@ -88,8 +87,15 @@ class RecipeIndex(Index): # # name, subtype, docname, anchor, extra, qualifier, description for _name, dispname, typ, docname, anchor, _priority in recipes: - content[dispname[0].lower()].append( - (dispname, 0, docname, anchor, docname, '', typ)) + content[dispname[0].lower()].append(( + dispname, + 0, + docname, + anchor, + docname, + '', + typ, + )) # convert the dict to the sorted list of tuples expected content = sorted(content.items()) @@ -98,7 +104,6 @@ class RecipeIndex(Index): class RecipeDomain(Domain): - name = 'recipe' label = 'Recipe Sample' roles = { @@ -122,18 +127,18 @@ class RecipeDomain(Domain): def get_objects(self): yield from self.data['recipes'] - def resolve_xref(self, env, fromdocname, builder, typ, target, node, - contnode): - match = [(docname, anchor) - for name, sig, typ, docname, anchor, prio - in self.get_objects() if sig == target] + def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + match = [ + (docname, anchor) + for name, sig, typ, docname, anchor, prio in self.get_objects() + if sig == target + ] if len(match) > 0: todocname = match[0][0] targ = match[0][1] - return make_refnode(builder, fromdocname, todocname, targ, - contnode, targ) + return make_refnode(builder, fromdocname, todocname, targ, contnode, targ) else: print('Awww, found nothing') return None @@ -145,8 +150,7 @@ class RecipeDomain(Domain): self.data['recipe_ingredients'][name] = ingredients # name, dispname, type, docname, anchor, priority - self.data['recipes'].append( - (name, signature, 'Recipe', self.env.docname, anchor, 0)) + self.data['recipes'].append((name, signature, 'Recipe', self.env.docname, anchor, 0)) def setup(app): diff --git a/doc/development/tutorials/examples/todo.py b/doc/development/tutorials/examples/todo.py index 82edd12fa..c84a5858e 100644 --- a/doc/development/tutorials/examples/todo.py +++ b/doc/development/tutorials/examples/todo.py @@ -22,13 +22,11 @@ def depart_todo_node(self, node): class TodolistDirective(Directive): - def run(self): return [todolist('')] class TodoDirective(SphinxDirective): - # this enables content in the directive has_content = True @@ -57,8 +55,7 @@ def purge_todos(app, env, docname): if not hasattr(env, 'todo_all_todos'): return - env.todo_all_todos = [todo for todo in env.todo_all_todos - if todo['docname'] != docname] + env.todo_all_todos = [todo for todo in env.todo_all_todos if todo['docname'] != docname] def merge_todos(app, env, docnames, other): @@ -90,17 +87,16 @@ def process_todo_nodes(app, doctree, fromdocname): for todo_info in env.todo_all_todos: para = nodes.paragraph() filename = env.doc2path(todo_info['docname'], base=None) - description = ( - _('(The original entry is located in %s, line %d and can be found ') % - (filename, todo_info['lineno'])) + description = _( + '(The original entry is located in %s, line %d and can be found ' + ) % (filename, todo_info['lineno']) para += nodes.Text(description) # Create a reference newnode = nodes.reference('', '') innernode = nodes.emphasis(_('here'), _('here')) newnode['refdocname'] = todo_info['docname'] - newnode['refuri'] = app.builder.get_relative_uri( - fromdocname, todo_info['docname']) + newnode['refuri'] = app.builder.get_relative_uri(fromdocname, todo_info['docname']) newnode['refuri'] += '#' + todo_info['target']['refid'] newnode.append(innernode) para += newnode @@ -119,10 +115,12 @@ def setup(app): app.add_config_value('todo_include_todos', False, 'html') app.add_node(todolist) - app.add_node(todo, - html=(visit_todo_node, depart_todo_node), - latex=(visit_todo_node, depart_todo_node), - text=(visit_todo_node, depart_todo_node)) + app.add_node( + todo, + html=(visit_todo_node, depart_todo_node), + latex=(visit_todo_node, depart_todo_node), + text=(visit_todo_node, depart_todo_node), + ) app.add_directive('todo', TodoDirective) app.add_directive('todolist', TodolistDirective) diff --git a/doc/usage/extensions/example_google.py b/doc/usage/extensions/example_google.py index 434fa3b67..7cd24d126 100644 --- a/doc/usage/extensions/example_google.py +++ b/doc/usage/extensions/example_google.py @@ -290,6 +290,7 @@ class ExampleClass: def _private_without_docstring(self): pass + class ExamplePEP526Class: """The summary line for a class docstring should fit on one line. diff --git a/doc/usage/extensions/example_numpy.py b/doc/usage/extensions/example_numpy.py index 2346b1ea9..d258ca3a3 100644 --- a/doc/usage/extensions/example_numpy.py +++ b/doc/usage/extensions/example_numpy.py @@ -266,7 +266,7 @@ class ExampleClass: self.attr3 = param3 #: Doc comment *inline* with attribute #: list(str): Doc comment *before* attribute, with type specified - self.attr4 = ["attr4"] + self.attr4 = ['attr4'] self.attr5 = None """str: Docstring *after* attribute, with type specified.""" @@ -274,7 +274,7 @@ class ExampleClass: @property def readonly_property(self): """str: Properties should be documented in their getter method.""" - return "readonly_property" + return 'readonly_property' @property def readwrite_property(self): @@ -284,7 +284,7 @@ class ExampleClass: If the setter method contains notable behavior, it should be mentioned here. """ - return ["readwrite_property"] + return ['readwrite_property'] @readwrite_property.setter def readwrite_property(self, value):