Question: Enable passing options to pygments Hi, Related to issue 175 (and discussed on #python-docs), it would be nice to have a way of passing options to pygments. This is essential for small snippets of PHP (the :startsinline: option) - there are probably other cases too. Default options might go in , with sourcecode block options allowed. Thanks Bitbucket: Originally reported by: Paul Biggar Originally created at: 2009-06-23T19:02:39.208

linenos = node.get('linenos', False)         highlight_args = node.get('highlight_args', {})         highlight_args['force'] = node.get('force', False)        if lang == self.config.highlight_language:            # only pass highlighter options for original language            opts = self.config.highlight_options        else:            opts = {}        opts = self.config.highlight_options.get(lang, {})          if linenos and self.config.html_codeblock_linenos_style:             linenos = self.config.html_codeblock_linenos_stylediff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py-- a/sphinx/writers/latex.py++ b/sphinx/writers/latex.py


Question: Enable passing options to pygments Hi, Related to issue 175 (and discussed on #python-docs), it would be nice to have a way of passing options to pygments. This is essential for small snippets of PHP (the :startsinline: option) - there are probably other cases too. Default options might go in , with sourcecode block options allowed. Thanks Bitbucket: Originally reported by: Paul Biggar Originally created at: 2009-06-23T19:02:39.208

linenos = node.get('linenos', False)             highlight_args = node.get('highlight_args', {})             highlight_args['force'] = node.get('force', False)            if lang == self.config.highlight_language:                # only pass highlighter options for original language                opts = self.config.highlight_options            else:                opts = {}            opts = self.config.highlight_options.get(lang, {})              hlcode = self.highlighter.highlight_block(                 node.rawsource, lang, opts=opts, linenos=linenos,


Question: reference pointing at a "rubric" directive containing a part breaks Describe the bug The reference text is broken when trying to display a reference pointing at a "rubric" directive containing a part that is. However, a title with a quoted text is rightfully displayed by a reference Will result in: ! To Reproduce Just use a directive with a quoted text in it, as shown below: from Expected behavior Text displayed by the reference should be displayed entirely Your project Environment info OS: alpine linux Python version: 3.7 Sphinx version: v3.4.1

name, env.doc2path(self.labels[name][0]),                                location=node)             self.anonlabels[name] = docname, labelid            if node.tagname in ('section', 'rubric'):            if node.tagname == 'section':                 title = cast(nodes.title, node[0])                 sectname = clean_astext(title)            elif node.tagname == 'rubric':                sectname = clean_astext(node)             elif self.is_enumerable_node(node):                 sectname = self.get_numfig_title(node)                 if not sectname:


Question: ROI: extend dedent for code-block and literalinclude Hi, I think it would be nice to let behave like the corresponding Python one: It may just that if nod edent value is provided, then a full dedent is performed.

"""  import sys<ins>import textwrap</ins> import warnings from difflib import unified_diff from typing import Any, Dict, List, Tuple


Question: ROI: extend dedent for code-block and literalinclude Hi, I think it would be nice to let behave like the corresponding Python one: It may just that if nod edent value is provided, then a full dedent is performed.

from sphinx import addnodes from sphinx.config import Config from sphinx.deprecation import RemovedInSphinx40Warning<ins>from sphinx.directives import optional_int</ins> from sphinx.locale import __ from sphinx.util import logging, parselinenos from sphinx.util.docutils import SphinxDirective


Question: ROI: extend dedent for code-block and literalinclude Hi, I think it would be nice to let behave like the corresponding Python one: It may just that if nod edent value is provided, then a full dedent is performed.

def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]:     if not dedent:        return lines        return textwrap.dedent(''.join(lines)).splitlines(True)      if any(s[:dedent].strip() for s in lines):         logger.warning(__('non-whitespace stripped by dedent'), location=location)


Question: ROI: extend dedent for code-block and literalinclude Hi, I think it would be nice to let behave like the corresponding Python one: It may just that if nod edent value is provided, then a full dedent is performed.

option_spec = {         'force': directives.flag,         'linenos': directives.flag,        'dedent': int,        'dedent': optional_int,         'lineno-start': int,         'emphasize-lines': directives.unchanged_required,         'caption': directives.unchanged_required,


Question: ROI: extend dedent for code-block and literalinclude Hi, I think it would be nice to let behave like the corresponding Python one: It may just that if nod edent value is provided, then a full dedent is performed.

optional_arguments = 0     final_argument_whitespace = True     option_spec = {        'dedent': int,        'dedent': optional_int,         'linenos': directives.flag,         'lineno-start': int,         'lineno-match': directives.flag,


Question: The reference to the same file is interpreted as a duplicate Tested on Windows 7 64bit machine, Python 2.7.3, Sphinx 1.1.3 If there is reference in various ways to the same resource, it is interpreted as different file with duplicate name. If there is a files structure as follows: And we have the following code in Then during the build of html output we will have three files (while only one is expected): The same issue is with figure directive. In attachment there is a simple Sphinx project just to illustrate the issue. IMO the problem is because all paths in Sphinx code are not normalized (() function is missing). Bitbucket: Originally reported by: Originally created at: 2013-02-18T14:47:34.934

import os import pickle<ins>import posixpath</ins> import warnings from collections import defaultdict from copy import copy


Question: The reference to the same file is interpreted as a duplicate Tested on Windows 7 64bit machine, Python 2.7.3, Sphinx 1.1.3 If there is reference in various ways to the same resource, it is interpreted as different file with duplicate name. If there is a files structure as follows: And we have the following code in Then during the build of html output we will have three files (while only one is expected): The same issue is with figure directive. In attachment there is a simple Sphinx project just to illustrate the issue. IMO the problem is because all paths in Sphinx code are not normalized (() function is missing). Bitbucket: Originally reported by: Originally created at: 2013-02-18T14:47:34.934

docdir = path.dirname(self.doc2path(docname or self.docname,                                                 base=None))             rel_fn = path.join(docdir, filename)        # the path.abspath() might seem redundant, but otherwise artifacts        # such as ".." will remain in the path        return rel_fn, path.abspath(path.join(self.srcdir, rel_fn))        return (posixpath.normpath(rel_fn),                path.normpath(path.join(self.srcdir, rel_fn)))      @property     def found_docs(self) -> Set[str]:


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

import posixpath import traceback<ins>import warnings</ins> from os import path from typing import Any, Dict, Generator, Iterable, Optional, Set, Tuple, cast


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

import sphinx from sphinx import addnodes from sphinx.application import Sphinxfrom sphinx.builders import Builder from sphinx.builders.html import StandaloneHTMLBuilderfrom sphinx.deprecation import RemovedInSphinx50Warning from sphinx.environment import BuildEnvironment from sphinx.locale import _, __ from sphinx.pycode import ModuleAnalyzerfrom sphinx.transforms.post_transforms import SphinxPostTransform from sphinx.util import get_full_modname, logging, status_iterator from sphinx.util.nodes import make_refnode


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

OUTPUT_DIRNAME = '_modules'  <ins>class viewcode_anchor(Element):    """Node for viewcode anchors.    This node will be processed in the resolving phase.    For viewcode supported builders, they will be all converted to the anchors.    For not supported builders, they will be removed.    """</ins> def _get_full_modname(app: Sphinx, modname: str, attribute: str) -> Optional[str]:     try:         return get_full_modname(modname, attribute)


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

return None  def is_supported_builder(builder: Builder) -> bool:    if builder.format != 'html':        return False    elif builder.name == 'singlehtml':        return False    elif builder.name.startswith('epub') and not builder.config.viewcode_enable_epub:        return False    else:        return True def doctree_read(app: Sphinx, doctree: Node) -> None:     env = app.builder.env     if not hasattr(env, '_viewcode_modules'):         env._viewcode_modules = {}  # type: ignore    if app.builder.name == "singlehtml":        return    if app.builder.name.startswith("epub") and not env.config.viewcode_enable_epub:        return      def has_tag(modname: str, fullname: str, docname: str, refname: str) -> bool:         entry = env._viewcode_modules.get(modname, None)  # type: ignore


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

continue             names.add(fullname)             pagename = posixpath.join(OUTPUT_DIRNAME, modname.replace('.', '/'))            inline = nodes.inline('', _('[source]'), classes=['viewcode-link'])            onlynode = addnodes.only(expr='html')            onlynode += addnodes.pending_xref('', inline, reftype='viewcode', refdomain='std',                                              refexplicit=False, reftarget=pagename,                                              refid=fullname, refdoc=env.docname)            signode += onlynode            signode += viewcode_anchor(reftarget=pagename, refid=fullname, refdoc=env.docname)   def env_merge_info(app: Sphinx, env: BuildEnvironment, docnames: Iterable[str],


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

env._viewcode_modules.update(other._viewcode_modules)  # type: ignore  class ViewcodeAnchorTransform(SphinxPostTransform):    """Convert or remove viewcode_anchor nodes depends on builder."""    default_priority = 100    def run(self, **kwargs: Any) -> None:        if is_supported_builder(self.app.builder):            self.convert_viewcode_anchors()        else:            self.remove_viewcode_anchors()    def convert_viewcode_anchors(self) -> None:        for node in self.document.traverse(viewcode_anchor):            anchor = nodes.inline('', _('[source]'), classes=['viewcode-link'])            refnode = make_refnode(self.app.builder, node['refdoc'], node['reftarget'],                                   node['refid'], anchor)            node.replace_self(refnode)    def remove_viewcode_anchors(self) -> None:        for node in self.document.traverse(viewcode_anchor):            node.parent.remove(node) def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnode: Node                       ) -> Optional[Node]:     # resolve our "viewcode" reference nodes -- they need special treatment     if node['reftype'] == 'viewcode':        warnings.warn('viewcode extension is no longer use pending_xref node. '                      'Please update your extension.', RemovedInSphinx50Warning)         return make_refnode(app.builder, node['refdoc'], node['reftarget'],                             node['refid'], contnode)


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

env = app.builder.env     if not hasattr(env, '_viewcode_modules'):         return    if app.builder.name == "singlehtml":        return    if app.builder.name.startswith("epub") and not env.config.viewcode_enable_epub:    if not is_supported_builder(app.builder):         return     highlighter = app.builder.highlighter  # type: ignore     urito = app.builder.get_relative_uri


Question: viewcode does not work when Describe the bug viewcode does not work when To Reproduce Expected behavior Always enabled for HTML builds (except singlehtml and epub) Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

# app.add_config_value('viewcode_exclude_modules', [], 'env')     app.add_event('viewcode-find-source')     app.add_event('viewcode-follow-imported')<ins>    app.add_post_transform(ViewcodeAnchorTransform)</ins>     return {         'version': sphinx.__display_version__,         'env_version': 1,


Question: napoleonuseparam should also affect "other parameters" section Subject: napoleonuseparam should also affect "other parameters" section Currently, napoleon always renders the Other parameters section as if napoleonuseparam was False, see source whereas it would make sense that this section should follow the same formatting rules as the Parameters section. Note the difference in rendering. See above. Alternatively another separate config value could be introduced, but that seems a bit overkill. N/A OS: Linux Python version: 3.7 Sphinx version: 1.8.1

return self._parse_generic_section(_('Notes'), use_admonition)      def _parse_other_parameters_section(self, section: str) -> List[str]:        return self._format_fields(_('Other Parameters'), self._consume_fields())        if self._config.napoleon_use_param:            # Allow to declare multiple parameters at once (ex: x, y: int)            fields = self._consume_fields(multiple=True)            return self._format_docutils_params(fields)        else:            fields = self._consume_fields()            return self._format_fields(_('Other Parameters'), fields)      def _parse_parameters_section(self, section: str) -> List[str]:         if self._config.napoleon_use_param:


Question: :kbd: role with Caps Lock rendered incorrectly Describe the bug Caps Lock` produces: Expected behavior Environment info OS: Debian unstable Python version: 3.9.1 Sphinx version:

"""  import refrom typing import Any, Dictfrom typing import Any, Dict, List  from docutils import nodes


Question: :kbd: role with Caps Lock rendered incorrectly Describe the bug Caps Lock` produces: Expected behavior Environment info OS: Debian unstable Python version: 3.9.1 Sphinx version:

default_priority = 400     builders = ('html',)     pattern = re.compile(r'(?<=.)(-|\+|\^|\s+)(?=.)')    multiwords_keys = (('caps', 'lock'),                       ('page' 'down'),                       ('page', 'up'),                       ('scroll' 'lock'),                       ('num', 'lock'),                       ('sys' 'rq'),                       ('back' 'space'))      def run(self, **kwargs: Any) -> None:         matcher = NodeMatcher(nodes.literal, classes=["kbd"])         for node in self.document.traverse(matcher):  # type: nodes.literal             parts = self.pattern.split(node[-1].astext())            if len(parts) == 1:            if len(parts) == 1 or self.is_multiwords_key(parts):                 continue              node['classes'].append('compound')             node.pop()             while parts:                key = parts.pop(0)                if self.is_multiwords_key(parts):                    key = ''.join(parts[:3])                    parts[:3] = []                else:                    key = parts.pop(0)                 node += nodes.literal('', key, classes=["kbd"])                  try:


Question: :kbd: role with Caps Lock rendered incorrectly Describe the bug Caps Lock` produces: Expected behavior Environment info OS: Debian unstable Python version: 3.9.1 Sphinx version:

except IndexError:                     pass <ins>    def is_multiwords_key(self, parts: List[str]) -> bool:        if len(parts) >= 3 and parts[1].strip() == '':            name = parts[0].lower(), parts[2].lower()            if name in self.multiwords_keys:                return True            else:                return False        else:            return False</ins>  def setup(app: Sphinx) -> Dict[str, Any]:     app.add_post_transform(KeyboardTransform)


Question: viewcode creates pages for epub even if on Describe the bug viewcode creates pages for epub even if on To Reproduce Expected behavior module pages should not be created for epub by default. Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

env = app.builder.env     if not hasattr(env, '_viewcode_modules'):         return<ins>    if app.builder.name == "singlehtml":        return    if app.builder.name.startswith("epub") and not env.config.viewcode_enable_epub:        return</ins>     highlighter = app.builder.highlighter  # type: ignore     urito = app.builder.get_relative_uri


Question: sphinx-apidoc on namespaces with only subpackages/namespaces Describe the bug --implicit-namespaces allows us to use namespaces in our project tree. At the current deployed implementation (3.4.3) it makes a difference if i have a submodule in my modulepath (root python namespace) or only subpackages/namespaces. Running with a submodule (some python file) it will choose the modulepath as the one and only module otherwise, without a submodule, it will use the subpackages/namespaces as individual python modules. The difference in the output is, that the of the modulepath is not created and does contain all subpackages/namespaces as submodules and not only the root module. I would recommend to introduce an option to not search recursively for modules, or disable the recursive search if implicit-namespaces are activated. To Reproduce Steps to reproduce the behavior: Expected behavior Expecting same result in apidoc_out2, with only one module inside Instead is missing and is different. Your project Environment info OS: Win Python version: 3.8.0 Sphinx version: 3.4.3

from fnmatch import fnmatch from importlib.machinery import EXTENSION_SUFFIXES from os import pathfrom typing import Any, List, Tuplefrom typing import Any, Generator, List, Tuple  import sphinx.locale from sphinx import __display_version__, package_dir


Question: sphinx-apidoc on namespaces with only subpackages/namespaces Describe the bug --implicit-namespaces allows us to use namespaces in our project tree. At the current deployed implementation (3.4.3) it makes a difference if i have a submodule in my modulepath (root python namespace) or only subpackages/namespaces. Running with a submodule (some python file) it will choose the modulepath as the one and only module otherwise, without a submodule, it will use the subpackages/namespaces as individual python modules. The difference in the output is, that the of the modulepath is not created and does contain all subpackages/namespaces as submodules and not only the root module. I would recommend to introduce an option to not search recursively for modules, or disable the recursive search if implicit-namespaces are activated. To Reproduce Steps to reproduce the behavior: Expected behavior Expecting same result in apidoc_out2, with only one module inside Instead is missing and is different. Your project Environment info OS: Win Python version: 3.8.0 Sphinx version: 3.4.3

return False  def walk(rootpath: str, excludes: List[str], opts: Any         ) -> Generator[Tuple[str, List[str], List[str]], None, None]:    """Walk through the directory and list files and subdirectories up."""    followlinks = getattr(opts, 'followlinks', False)    includeprivate = getattr(opts, 'includeprivate', False)    for root, subs, files in os.walk(rootpath, followlinks=followlinks):        # document only Python module files (that aren't excluded)        files = sorted(f for f in files                       if f.endswith(PY_SUFFIXES) and                       not is_excluded(path.join(root, f), excludes))        # remove hidden ('.') and private ('_') directories, as well as        # excluded dirs        if includeprivate:            exclude_prefixes = ('.',)  # type: Tuple[str, ...]        else:            exclude_prefixes = ('.', '_')        subs[:] = sorted(sub for sub in subs if not sub.startswith(exclude_prefixes) and                         not is_excluded(path.join(root, sub), excludes))        yield root, subs, filesdef has_child_module(rootpath: str, excludes: List[str], opts: Any) -> bool:    """Check the given directory contains child modules at least one."""    for root, subs, files in walk(rootpath, excludes, opts):        if files:            return True    return False def recurse_tree(rootpath: str, excludes: List[str], opts: Any,                  user_template_dir: str = None) -> List[str]:     """     Look for every file in the directory tree and create the corresponding     ReST files.     """    followlinks = getattr(opts, 'followlinks', False)    includeprivate = getattr(opts, 'includeprivate', False)     implicit_namespaces = getattr(opts, 'implicit_namespaces', False)      # check if the base directory is a package and get its name


Question: sphinx-apidoc on namespaces with only subpackages/namespaces Describe the bug --implicit-namespaces allows us to use namespaces in our project tree. At the current deployed implementation (3.4.3) it makes a difference if i have a submodule in my modulepath (root python namespace) or only subpackages/namespaces. Running with a submodule (some python file) it will choose the modulepath as the one and only module otherwise, without a submodule, it will use the subpackages/namespaces as individual python modules. The difference in the output is, that the of the modulepath is not created and does contain all subpackages/namespaces as submodules and not only the root module. I would recommend to introduce an option to not search recursively for modules, or disable the recursive search if implicit-namespaces are activated. To Reproduce Steps to reproduce the behavior: Expected behavior Expecting same result in apidoc_out2, with only one module inside Instead is missing and is different. Your project Environment info OS: Win Python version: 3.8.0 Sphinx version: 3.4.3

root_package = None      toplevels = []    for root, subs, files in os.walk(rootpath, followlinks=followlinks):        # document only Python module files (that aren't excluded)        py_files = sorted(f for f in files                          if f.endswith(PY_SUFFIXES) and                          not is_excluded(path.join(root, f), excludes))        is_pkg = is_packagedir(None, py_files)    for root, subs, files in walk(rootpath, excludes, opts):        is_pkg = is_packagedir(None, files)         is_namespace = not is_pkg and implicit_namespaces         if is_pkg:            for f in py_files[:]:            for f in files[:]:                 if is_initpy(f):                    py_files.remove(f)                    py_files.insert(0, f)                    files.remove(f)                    files.insert(0, f)         elif root != rootpath:             # only accept non-package at toplevel unless using implicit namespaces             if not implicit_namespaces:                 del subs[:]                 continue        # remove hidden ('.') and private ('_') directories, as well as        # excluded dirs        if includeprivate:            exclude_prefixes = ('.',)  # type: Tuple[str, ...]        else:            exclude_prefixes = ('.', '_')        subs[:] = sorted(sub for sub in subs if not sub.startswith(exclude_prefixes) and                         not is_excluded(path.join(root, sub), excludes))          if is_pkg or is_namespace:             # we are in a package with something to document            if subs or len(py_files) > 1 or not is_skipped_package(root, opts):            if subs or len(files) > 1 or not is_skipped_package(root, opts):                 subpackage = root[len(rootpath):].lstrip(path.sep).\                     replace(path.sep, '.')                 # if this is not a namespace or                 # a namespace and there is something there to document                if not is_namespace or len(py_files) > 0:                if not is_namespace or has_child_module(root, excludes, opts):                     create_package_file(root, root_package, subpackage,                                        py_files, opts, subs, is_namespace, excludes,                                        files, opts, subs, is_namespace, excludes,                                         user_template_dir)                     toplevels.append(module_join(root_package, subpackage))         else:             # if we are at the root level, we don't require it to be a package             assert root == rootpath and root_package is None            for py_file in py_files:            for py_file in files:                 if not is_skipped_module(path.join(rootpath, py_file), opts, excludes):                     module = py_file.split('.')[0]                     create_module_file(root_package, module, opts, user_template_dir)


Question: Return type for Yield attribute not properly hyperlinked in apidocs Describe the bug Typically when one defines a return value in a method they will use the following syntax: When doing so the return type, in this case, is hyperlinked to the api docs for the appropriate data type (ie: using interphinx). However, when writing doc strings for generators using the same / similar syntax provided by the Yield attribute, the data type associated with the generator is not appropriately decorated. Taking the previous example code snippet and making a small modification as show below is sufficient to demonstrate the change in behavior: The HTML markup produced by this code snippet simply format the data type using custom font formatting based on the theme, but it fails to associate / generate the hyperlink for the API docs for the data type as is done by the Return attribute. NOTE: I am using the apidocs Sphinx extension to generate the API docs for my projects in case that has any impact on this behavior. To Reproduce Steps to reproduce the behavior: Expected behavior The data type should be decorated / marked up the same way it appears when using the Return attribute when using the Yield attribute Your project Screenshots Example output generated on ReadTheDocs: Environment info OS: MacOS Python version: 3.8.0 Sphinx version: 3.1.2 Sphinx extensions: , , Extra tools: any web browser (safari, chrome, firefox, IE) Additional context (I thought this might be a bug with the napoleon extension so I reported it here first, but they recommended I report the issue here instead)

_SINGLETONS = ("None", "True", "False", "Ellipsis")  <ins>def _convert_type_spec(_type: str, translations: Dict[str, str] = {}) -> str:    """Convert type specification to reference in reST."""    if _type in translations:        return translations[_type]    else:        if _type == 'None':            return ':obj:`None`'        else:            return ':class:`%s`' % _type    return _type</ins> class GoogleDocstring:     """Convert Google style docstrings to reStructuredText.


Question: Return type for Yield attribute not properly hyperlinked in apidocs Describe the bug Typically when one defines a return value in a method they will use the following syntax: When doing so the return type, in this case, is hyperlinked to the api docs for the appropriate data type (ie: using interphinx). However, when writing doc strings for generators using the same / similar syntax provided by the Yield attribute, the data type associated with the generator is not appropriately decorated. Taking the previous example code snippet and making a small modification as show below is sufficient to demonstrate the change in behavior: The HTML markup produced by this code snippet simply format the data type using custom font formatting based on the theme, but it fails to associate / generate the hyperlink for the API docs for the data type as is done by the Return attribute. NOTE: I am using the apidocs Sphinx extension to generate the API docs for my projects in case that has any impact on this behavior. To Reproduce Steps to reproduce the behavior: Expected behavior The data type should be decorated / marked up the same way it appears when using the Return attribute when using the Yield attribute Your project Screenshots Example output generated on ReadTheDocs: Environment info OS: MacOS Python version: 3.8.0 Sphinx version: 3.1.2 Sphinx extensions: , , Extra tools: any web browser (safari, chrome, firefox, IE) Additional context (I thought this might be a bug with the napoleon extension so I reported it here first, but they recommended I report the issue here instead)

if prefer_type and not _type:             _type, _name = _name, _type<ins>        if _type and self._config.napoleon_preprocess_types:            _type = _convert_type_spec(_type, self._config.napoleon_type_aliases or {})</ins>         indent = self._get_indent(line) + 1         _descs = [_desc] + self._dedent(self._consume_indented_block(indent))         _descs = self.__class__(_descs, self._config).lines()


Question: Return type for Yield attribute not properly hyperlinked in apidocs Describe the bug Typically when one defines a return value in a method they will use the following syntax: When doing so the return type, in this case, is hyperlinked to the api docs for the appropriate data type (ie: using interphinx). However, when writing doc strings for generators using the same / similar syntax provided by the Yield attribute, the data type associated with the generator is not appropriately decorated. Taking the previous example code snippet and making a small modification as show below is sufficient to demonstrate the change in behavior: The HTML markup produced by this code snippet simply format the data type using custom font formatting based on the theme, but it fails to associate / generate the hyperlink for the API docs for the data type as is done by the Return attribute. NOTE: I am using the apidocs Sphinx extension to generate the API docs for my projects in case that has any impact on this behavior. To Reproduce Steps to reproduce the behavior: Expected behavior The data type should be decorated / marked up the same way it appears when using the Return attribute when using the Yield attribute Your project Screenshots Example output generated on ReadTheDocs: Environment info OS: MacOS Python version: 3.8.0 Sphinx version: 3.1.2 Sphinx extensions: , , Extra tools: any web browser (safari, chrome, firefox, IE) Additional context (I thought this might be a bug with the napoleon extension so I reported it here first, but they recommended I report the issue here instead)

_descs = self.__class__(_descs, self._config).lines()         return _type, _descs     def _consume_returns_section(self) -> List[Tuple[str, str, List[str]]]:    def _consume_returns_section(self, preprocess_types: bool = False                                 ) -> List[Tuple[str, str, List[str]]]:         lines = self._dedent(self._consume_to_next_section())         if lines:             before, colon, after = self._partition_field_on_colon(lines[0])


Question: Return type for Yield attribute not properly hyperlinked in apidocs Describe the bug Typically when one defines a return value in a method they will use the following syntax: When doing so the return type, in this case, is hyperlinked to the api docs for the appropriate data type (ie: using interphinx). However, when writing doc strings for generators using the same / similar syntax provided by the Yield attribute, the data type associated with the generator is not appropriately decorated. Taking the previous example code snippet and making a small modification as show below is sufficient to demonstrate the change in behavior: The HTML markup produced by this code snippet simply format the data type using custom font formatting based on the theme, but it fails to associate / generate the hyperlink for the API docs for the data type as is done by the Return attribute. NOTE: I am using the apidocs Sphinx extension to generate the API docs for my projects in case that has any impact on this behavior. To Reproduce Steps to reproduce the behavior: Expected behavior The data type should be decorated / marked up the same way it appears when using the Return attribute when using the Yield attribute Your project Screenshots Example output generated on ReadTheDocs: Environment info OS: MacOS Python version: 3.8.0 Sphinx version: 3.1.2 Sphinx extensions: , , Extra tools: any web browser (safari, chrome, firefox, IE) Additional context (I thought this might be a bug with the napoleon extension so I reported it here first, but they recommended I report the issue here instead)

_type = before <ins>            if (_type and preprocess_types and                    self._config.napoleon_preprocess_types):                _type = _convert_type_spec(_type, self._config.napoleon_type_aliases or {})</ins>             _desc = self.__class__(_desc, self._config).lines()             return [(_name, _type, _desc,)]         else:


Question: Return type for Yield attribute not properly hyperlinked in apidocs Describe the bug Typically when one defines a return value in a method they will use the following syntax: When doing so the return type, in this case, is hyperlinked to the api docs for the appropriate data type (ie: using interphinx). However, when writing doc strings for generators using the same / similar syntax provided by the Yield attribute, the data type associated with the generator is not appropriately decorated. Taking the previous example code snippet and making a small modification as show below is sufficient to demonstrate the change in behavior: The HTML markup produced by this code snippet simply format the data type using custom font formatting based on the theme, but it fails to associate / generate the hyperlink for the API docs for the data type as is done by the Return attribute. NOTE: I am using the apidocs Sphinx extension to generate the API docs for my projects in case that has any impact on this behavior. To Reproduce Steps to reproduce the behavior: Expected behavior The data type should be decorated / marked up the same way it appears when using the Return attribute when using the Yield attribute Your project Screenshots Example output generated on ReadTheDocs: Environment info OS: MacOS Python version: 3.8.0 Sphinx version: 3.1.2 Sphinx extensions: , , Extra tools: any web browser (safari, chrome, firefox, IE) Additional context (I thought this might be a bug with the napoleon extension so I reported it here first, but they recommended I report the issue here instead)

return self._format_fields(section, self._consume_fields())      def _parse_custom_returns_style_section(self, section: str) -> List[str]:        fields = self._consume_returns_section()        fields = self._consume_returns_section(preprocess_types=True)         return self._format_fields(section, fields)      def _parse_usage_section(self, section: str) -> List[str]:


Question: Return type for Yield attribute not properly hyperlinked in apidocs Describe the bug Typically when one defines a return value in a method they will use the following syntax: When doing so the return type, in this case, is hyperlinked to the api docs for the appropriate data type (ie: using interphinx). However, when writing doc strings for generators using the same / similar syntax provided by the Yield attribute, the data type associated with the generator is not appropriately decorated. Taking the previous example code snippet and making a small modification as show below is sufficient to demonstrate the change in behavior: The HTML markup produced by this code snippet simply format the data type using custom font formatting based on the theme, but it fails to associate / generate the hyperlink for the API docs for the data type as is done by the Return attribute. NOTE: I am using the apidocs Sphinx extension to generate the API docs for my projects in case that has any impact on this behavior. To Reproduce Steps to reproduce the behavior: Expected behavior The data type should be decorated / marked up the same way it appears when using the Return attribute when using the Yield attribute Your project Screenshots Example output generated on ReadTheDocs: Environment info OS: MacOS Python version: 3.8.0 Sphinx version: 3.1.2 Sphinx extensions: , , Extra tools: any web browser (safari, chrome, firefox, IE) Additional context (I thought this might be a bug with the napoleon extension so I reported it here first, but they recommended I report the issue here instead)

return self._format_fields(_('Warns'), self._consume_fields())      def _parse_yields_section(self, section: str) -> List[str]:        fields = self._consume_returns_section()        fields = self._consume_returns_section(preprocess_types=True)         return self._format_fields(_('Yields'), fields)      def _partition_field_on_colon(self, line: str) -> Tuple[str, str, str]:


Question: Return type for Yield attribute not properly hyperlinked in apidocs Describe the bug Typically when one defines a return value in a method they will use the following syntax: When doing so the return type, in this case, is hyperlinked to the api docs for the appropriate data type (ie: using interphinx). However, when writing doc strings for generators using the same / similar syntax provided by the Yield attribute, the data type associated with the generator is not appropriately decorated. Taking the previous example code snippet and making a small modification as show below is sufficient to demonstrate the change in behavior: The HTML markup produced by this code snippet simply format the data type using custom font formatting based on the theme, but it fails to associate / generate the hyperlink for the API docs for the data type as is done by the Return attribute. NOTE: I am using the apidocs Sphinx extension to generate the API docs for my projects in case that has any impact on this behavior. To Reproduce Steps to reproduce the behavior: Expected behavior The data type should be decorated / marked up the same way it appears when using the Return attribute when using the Yield attribute Your project Screenshots Example output generated on ReadTheDocs: Environment info OS: MacOS Python version: 3.8.0 Sphinx version: 3.1.2 Sphinx extensions: , , Extra tools: any web browser (safari, chrome, firefox, IE) Additional context (I thought this might be a bug with the napoleon extension so I reported it here first, but they recommended I report the issue here instead)

_desc = self.__class__(_desc, self._config).lines()         return _name, _type, _desc     def _consume_returns_section(self) -> List[Tuple[str, str, List[str]]]:    def _consume_returns_section(self, preprocess_types: bool = False                                 ) -> List[Tuple[str, str, List[str]]]:         return self._consume_fields(prefer_type=True)      def _consume_section_header(self) -> str:


Question: Keeping original signatures for functions/methods I'm using Sphinx's autodoc feature to document my API. Example: The generated documentation now shows the following signature: It would be nice if there was a way to tell Sphinx to keep the name of the constant value, i.e. At the moment the only alternative is to write all signature by hand again. Bitbucket: Originally reported by: Sebastian Rahlf Originally created at: 2011-08-31T11:29:50.797

app.connect('config-inited', migrate_autodoc_member_order, priority=800)     app.setup_extension('sphinx.ext.autodoc.preserve_defaults')     app.setup_extension('sphinx.ext.autodoc.type_comment')     app.setup_extension('sphinx.ext.autodoc.typehints') diff --git a/sphinx/ext/autodoc/preserve_defaults.py b/sphinx/ext/autodoc/preserve_defaults.pynew file mode 100644-- /dev/null++ b/sphinx/ext/autodoc/preserve_defaults.py


Question: Keeping original signatures for functions/methods I'm using Sphinx's autodoc feature to document my API. Example: The generated documentation now shows the following signature: It would be nice if there was a way to tell Sphinx to keep the name of the constant value, i.e. At the moment the only alternative is to write all signature by hand again. Bitbucket: Originally reported by: Sebastian Rahlf Originally created at: 2011-08-31T11:29:50.797

<ins>"""    sphinx.ext.autodoc.preserve_defaults    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    Preserve the default argument values of function signatures in source code    and keep them not evaluated for readability.    :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.    :license: BSD, see LICENSE for details."""import astimport inspectfrom typing import Any, Dictfrom sphinx.application import Sphinxfrom sphinx.locale import __from sphinx.pycode.ast import parse as ast_parsefrom sphinx.pycode.ast import unparse as ast_unparsefrom sphinx.util import logginglogger = logging.getLogger(__name__)class DefaultValue:    def __init__(self, name: str) -> None:        self.name = name    def __repr__(self) -> str:        return self.namedef get_function_def(obj: Any) -> ast.FunctionDef:    """Get FunctionDef object from living object.    This tries to parse original code for living object and returns    AST node for given *obj*.    """    try:        source = inspect.getsource(obj)        if source.startswith((' ', r'\t')):            # subject is placed inside class or block.  To read its docstring,            # this adds if-block before the declaration.            module = ast_parse('if True:\n' + source)            return module.body[0].body[0]  # type: ignore        else:            module = ast_parse(source)            return module.body[0]  # type: ignore    except (OSError, TypeError):  # failed to load source code        return Nonedef update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None:    """Update defvalue info of *obj* using type_comments."""    if not app.config.autodoc_preserve_defaults:        return    try:        function = get_function_def(obj)        if function.args.defaults or function.args.kw_defaults:            sig = inspect.signature(obj)            defaults = list(function.args.defaults)            kw_defaults = list(function.args.kw_defaults)            parameters = list(sig.parameters.values())            for i, param in enumerate(parameters):                if param.default is not param.empty:                    if param.kind in (param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD):                        value = DefaultValue(ast_unparse(defaults.pop(0)))  # type: ignore                        parameters[i] = param.replace(default=value)                    else:                        value = DefaultValue(ast_unparse(kw_defaults.pop(0)))  # type: ignore                        parameters[i] = param.replace(default=value)            sig = sig.replace(parameters=parameters)            obj.__signature__ = sig    except (AttributeError, TypeError):        # failed to update signature (ex. built-in or extension types)        pass    except NotImplementedError as exc:  # failed to ast.unparse()        logger.warning(__("Failed to parse a default argument value for %r: %s"), obj, exc)def setup(app: Sphinx) -> Dict[str, Any]:    app.add_config_value('autodoc_preserve_defaults', False, True)    app.connect('autodoc-before-process-signature', update_defvalue)    return {        'version': '1.0',        'parallel_read_safe': True    }</ins>


Question: autodoc: The annotation only member in superclass is treated as "undocumented" Describe the bug autodoc: The annotation only member in superclass is treated as "undocumented". To Reproduce is not documented. It will be shown if I give option to the autoclass directive call. It seems the attribute is treated as undocumented. Expected behavior It should be shown. Your project No Screenshots No Environment info OS: Mac Python version: 3.9.1 Sphinx version: HEAD of 3.x Sphinx extensions: Extra tools: No Additional context No

try:         for cls in getmro(subject):            try:                modname = safe_getattr(cls, '__module__')                qualname = safe_getattr(cls, '__qualname__')                analyzer = ModuleAnalyzer.for_module(modname)                analyzer.analyze()            except AttributeError:                qualname = None                analyzer = None            except PycodeError:                analyzer = None             # annotation only member (ex. attr: int)             for name in getannotations(cls):                 name = unmangle(cls, name)                 if name and name not in members:                    members[name] = ObjectMember(name, INSTANCEATTR, class_=cls)                    if analyzer and (qualname, name) in analyzer.attr_docs:                        docstring = '\n'.join(analyzer.attr_docs[qualname, name])                    else:                        docstring = None                    members[name] = ObjectMember(name, INSTANCEATTR, class_=cls,                                                 docstring=docstring)              # append instance attributes (cf. self.attr1) if analyzer knows            try:                modname = safe_getattr(cls, '__module__')                qualname = safe_getattr(cls, '__qualname__')                analyzer = ModuleAnalyzer.for_module(modname)                analyzer.analyze()            if analyzer:                 for (ns, name), docstring in analyzer.attr_docs.items():                     if ns == qualname and name not in members:                         members[name] = ObjectMember(name, INSTANCEATTR, class_=cls,                                                      docstring='\n'.join(docstring))            except (AttributeError, PycodeError):                pass     except AttributeError:         pass


Question: [LaTex] code-block printed out of margin this is not handled correctly currently: long hex strings ! code: ` link to rst file: Originally posted by in

def visit_footnote(self, node: Element) -> None:         self.in_footnote += 1         label = cast(nodes.label, node[0])        if 'auto' not in node:            self.body.append('\\sphinxstepexplicit ')         if self.in_parsed_literal:             self.body.append('\\begin{footnote}[%s]' % label.astext())         else:             self.body.append('%\n')             self.body.append('\\begin{footnote}[%s]' % label.astext())        if 'auto' not in node:            self.body.append('\\phantomsection'                             '\\label{\\thesphinxscope.%s}%%\n' % label.astext())         self.body.append('\\sphinxAtStartFootnote\n')      def depart_footnote(self, node: Element) -> None:


Question: [LaTex] code-block printed out of margin this is not handled correctly currently: long hex strings ! code: ` link to rst file: Originally posted by in

label = cast(nodes.label, node[0])         self.body.append('%\n')         self.body.append('\\begin{footnotetext}[%s]'                         '\\sphinxAtStartFootnote\n' % label.astext())                         '\\phantomsection\\label{\\thesphinxscope.%s}%%\n'                         % (label.astext(), label.astext()))        self.body.append('\\sphinxAtStartFootnote\n')      def depart_footnotetext(self, node: Element) -> None:         # the \ignorespaces in particular for after table header use


Question: Support C++20's spaceship operator C++20 has the new spaceship operator for three way comparisons which can also be (not sure if the latter matters to Sphinx). I hope this is a problem with Sphinx at all and not with the Breathe extension I'm also using. For example, this reST code in Sphinx currently leads to the following warning/error

|   \+\+ | --     |   ->\*? | \,     |   (<<|>>)=? | && | \|\|<ins>    |   <=></ins>     |   [!<>=/*%+|&^~-]=?     |   (\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|xor|xor_eq)\b) ''')


Question: Support C++20's spaceship operator C++20 has the new spaceship operator for three way comparisons which can also be (not sure if the latter matters to Sphinx). I hope this is a problem with Sphinx at all and not with the Breathe extension I'm also using. For example, this reST code in Sphinx currently leads to the following warning/error

'>': 'gt',     '<=': 'le',     '>=': 'ge',<ins>    '<=>': 'ss',</ins>     '!': 'nt', 'not': 'nt',     '&&': 'aa', 'and': 'aa',     '||': 'oo', 'or': 'oo',


Question: Support C++20's spaceship operator C++20 has the new spaceship operator for three way comparisons which can also be (not sure if the latter matters to Sphinx). I hope this is a problem with Sphinx at all and not with the Breathe extension I'm also using. For example, this reST code in Sphinx currently leads to the following warning/error

['^', 'xor'],     ['&', 'bitand'],     ['==', '!=', 'not_eq'],    ['<=', '>=', '<', '>'],    ['<=>', '<=', '>=', '<', '>'],     ['<<', '>>'],     ['+', '-'],     ['*', '/', '%'],


Question: Support C++20's spaceship operator C++20 has the new spaceship operator for three way comparisons which can also be (not sure if the latter matters to Sphinx). I hope this is a problem with Sphinx at all and not with the Breathe extension I'm also using. For example, this reST code in Sphinx currently leads to the following warning/error

# exclusive-or   = and              ^         # and            = equality         &         # equality       = relational       ==, !=        # relational     = shift            <, >, <=, >=        # relational     = shift            <, >, <=, >=, <=>         # shift          = additive         <<, >>         # additive       = multiplicative   +, -         # multiplicative = pm               *, /, %


Question: Absolute/"source-relative" imports for csv-table :file: Describe the bug To be honest, I am not sure if this can be considered a bug, or if it is rather a feature request. Sorry about that. When using the directive, the use of with absolute paths are really absolute, unlike with (eg) the directive, where absolute paths are treated relative to the source directory (herein called "source-relative"). I do understand that there is a difference in the 2 cases, because with the path is not specified in . Yet, I do not see a possibility to mimic this behavior in the directive. To Reproduce A file in : Relative imports: are treated, as expected, relative to the file: Absolute imports: are treated, opposed to my expectations, like real absolute paths: and not like relative-to-source paths. Expected behavior I would expect this to work like absolute paths in the (eg) directive. But as stated in the beginning, probably I am wrong with my expectation, and this should be a feature request to add an option to use "source-relative" paths with the directive. Environment info OS: Win Python version: 3.8.5 Sphinx version: 3.2.1

:license: BSD, see LICENSE for details. """ import os import warningsfrom os import path from typing import TYPE_CHECKING, Any, Dict, List, Tuple, cast  from docutils import nodes


Question: Absolute/"source-relative" imports for csv-table :file: Describe the bug To be honest, I am not sure if this can be considered a bug, or if it is rather a feature request. Sorry about that. When using the directive, the use of with absolute paths are really absolute, unlike with (eg) the directive, where absolute paths are treated relative to the source directory (herein called "source-relative"). I do understand that there is a difference in the 2 cases, because with the path is not specified in . Yet, I do not see a possibility to mimic this behavior in the directive. To Reproduce A file in : Relative imports: are treated, as expected, relative to the file: Absolute imports: are treated, opposed to my expectations, like real absolute paths: and not like relative-to-source paths. Expected behavior I would expect this to work like absolute paths in the (eg) directive. But as stated in the beginning, probably I am wrong with my expectation, and this should be a feature request to add an option to use "source-relative" paths with the directive. Environment info OS: Win Python version: 3.8.5 Sphinx version: 3.2.1

from sphinx.deprecation import RemovedInSphinx60Warning from sphinx.directives import optional_int from sphinx.domains.math import MathDomainfrom sphinx.locale import __from sphinx.util import logging from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import set_source_infofrom sphinx.util.osutil import SEP, os_path, relpath  if TYPE_CHECKING:     from sphinx.application import Sphinx  logger = logging.getLogger(__name__) class Figure(images.Figure):     """The figure directive which applies `:name:` option to the figure node     instead of the image node.


Question: Absolute/"source-relative" imports for csv-table :file: Describe the bug To be honest, I am not sure if this can be considered a bug, or if it is rather a feature request. Sorry about that. When using the directive, the use of with absolute paths are really absolute, unlike with (eg) the directive, where absolute paths are treated relative to the source directory (herein called "source-relative"). I do understand that there is a difference in the 2 cases, because with the path is not specified in . Yet, I do not see a possibility to mimic this behavior in the directive. To Reproduce A file in : Relative imports: are treated, as expected, relative to the file: Absolute imports: are treated, opposed to my expectations, like real absolute paths: and not like relative-to-source paths. Expected behavior I would expect this to work like absolute paths in the (eg) directive. But as stated in the beginning, probably I am wrong with my expectation, and this should be a feature request to add an option to use "source-relative" paths with the directive. Environment info OS: Win Python version: 3.8.5 Sphinx version: 3.2.1

class CSVTable(tables.CSVTable):    """The csv-table directive which sets source and line information to its caption.    Only for docutils-0.13 or older version."""    """The csv-table directive which searches a CSV file from Sphinx project's source    directory when an absolute path is given via :file: option.    """      def run(self) -> List[Node]:        warnings.warn('CSVTable is deprecated.',                      RemovedInSphinx60Warning)        return super().run()        if 'file' in self.options and self.options['file'].startswith((SEP, os.sep)):            env = self.state.document.settings.env            filename = self.options['file']            if path.exists(filename):                logger.warning(__('":file:" option for csv-table directive now recognizes '                                  'an absolute path as a relative path from source directory. '                                  'Please update your document.'),                               location=(env.docname, self.lineno))            else:                abspath = path.join(env.srcdir, os_path(self.options['file'][1:]))                docdir = path.dirname(env.doc2path(env.docname))                self.options['file'] = relpath(abspath, docdir)     def make_title(self) -> Tuple[nodes.title, List[system_message]]:        title, message = super().make_title()        if title:            set_source_info(self, title)        return title, message        return super().run()   class ListTable(tables.ListTable):


Question: Absolute/"source-relative" imports for csv-table :file: Describe the bug To be honest, I am not sure if this can be considered a bug, or if it is rather a feature request. Sorry about that. When using the directive, the use of with absolute paths are really absolute, unlike with (eg) the directive, where absolute paths are treated relative to the source directory (herein called "source-relative"). I do understand that there is a difference in the 2 cases, because with the path is not specified in . Yet, I do not see a possibility to mimic this behavior in the directive. To Reproduce A file in : Relative imports: are treated, as expected, relative to the file: Absolute imports: are treated, opposed to my expectations, like real absolute paths: and not like relative-to-source paths. Expected behavior I would expect this to work like absolute paths in the (eg) directive. But as stated in the beginning, probably I am wrong with my expectation, and this should be a feature request to add an option to use "source-relative" paths with the directive. Environment info OS: Win Python version: 3.8.5 Sphinx version: 3.2.1

def setup(app: "Sphinx") -> Dict[str, Any]:     directives.register_directive('figure', Figure)     directives.register_directive('meta', Meta)<ins>    directives.register_directive('csv-table', CSVTable)</ins>     directives.register_directive('code', Code)     directives.register_directive('math', MathDirective)


Question: Property gets linked instead of external type in class with inline type annotations Describe the bug The project is using autodoc with inline Python type annotations. Given the following class (snipped to the relevant parts): The class and method get rendered : ! In the class, the gets rendered as and is not linked. In the method, the gets rendered as and links to the property. Expected behavior I expect it to show as . A is also OK I guess (if it's meant to refer to a "traceback object"), but in that case it should link to or instead of the local property. To Reproduce I can try to create a minimal reproduction if the above is not sufficient or gets outdated. Your project Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Sphinx extensions:

import sys import typing from struct import Struct<ins>from types import TracebackType</ins> from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, TypeVar, Union  from docutils import nodes


Question: Property gets linked instead of external type in class with inline type annotations Describe the bug The project is using autodoc with inline Python type annotations. Given the following class (snipped to the relevant parts): The class and method get rendered : ! In the class, the gets rendered as and is not linked. In the method, the gets rendered as and links to the property. Expected behavior I expect it to show as . A is also OK I guess (if it's meant to refer to a "traceback object"), but in that case it should link to or instead of the local property. To Reproduce I can try to create a minimal reproduction if the above is not sufficient or gets outdated. Your project Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Sphinx extensions:

from typing import Type  # NOQA # for python3.5.1  <ins># builtin classes that have incorrect __module__INVALID_BUILTIN_CLASSES = {    Struct: 'struct.Struct',  # Before Python 3.9    TracebackType: 'types.TracebackType',}</ins> # Text like nodes which are initialized with text and rawsource TextlikeNode = Union[nodes.Text, nodes.TextElement]


Question: Property gets linked instead of external type in class with inline type annotations Describe the bug The project is using autodoc with inline Python type annotations. Given the following class (snipped to the relevant parts): The class and method get rendered : ! In the class, the gets rendered as and is not linked. In the method, the gets rendered as and links to the property. Expected behavior I expect it to show as . A is also OK I guess (if it's meant to refer to a "traceback object"), but in that case it should link to or instead of the local property. To Reproduce I can try to create a minimal reproduction if the above is not sufficient or gets outdated. Your project Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Sphinx extensions:

return ':obj:`None`'     elif cls is Ellipsis:         return '...'    elif cls is Struct:        # Before Python 3.9, struct.Struct class has incorrect __module__.        return ':class:`struct.Struct`'    elif cls in INVALID_BUILTIN_CLASSES:        return ':class:`%s`' % INVALID_BUILTIN_CLASSES[cls]     elif inspect.isNewType(cls):         return ':class:`%s`' % cls.__name__     elif types_Union and isinstance(cls, types_Union):


Question: Property gets linked instead of external type in class with inline type annotations Describe the bug The project is using autodoc with inline Python type annotations. Given the following class (snipped to the relevant parts): The class and method get rendered : ! In the class, the gets rendered as and is not linked. In the method, the gets rendered as and links to the property. Expected behavior I expect it to show as . A is also OK I guess (if it's meant to refer to a "traceback object"), but in that case it should link to or instead of the local property. To Reproduce I can try to create a minimal reproduction if the above is not sufficient or gets outdated. Your project Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Sphinx extensions:

return repr(annotation)     elif annotation is NoneType:         return 'None'    elif annotation in INVALID_BUILTIN_CLASSES:        return INVALID_BUILTIN_CLASSES[annotation]     elif (getattr(annotation, '__module__', None) == 'builtins' and           hasattr(annotation, '__qualname__')):         return annotation.__qualname__     elif annotation is Ellipsis:         return '...'    elif annotation is Struct:        # Before Python 3.9, struct.Struct class has incorrect __module__.        return 'struct.Struct'      if sys.version_info >= (3, 7):  # py37+         return _stringify_py37(annotation)


Question: WARNING: py:class reference target not found: .. Describe the bug I think this might be referring to the ellipsis but I'm not sure at present. Note that I've already tracked the other warnings (outcomes and event type) to other issues. This time I did remember to try latest 3.x (). It showed the same issue. To Reproduce Steps to reproduce the behavior: <details<summarySteps with output including complete traceback</summary</detailsExpected behavior I'm not completely sure but at least a reference to a specific thing in my code. If it is referring to the ellipsis then perhaps it just shouldn't have an issue at all. I'm guessing it should just be a plain in the output. It could link to but that doesn't really describe it's meaning in typing and the generic type for which it is a parameter would already be linked. Your project Environment info OS: Ubuntu Linux 20.04 Python version: 3.8.3 Sphinx version: 3.2.0 Sphinx extensions: sphinxqtdocumentation sphinxcontribtrio

def make_xrefs(self, rolename: str, domain: str, target: str,                    innernode: Type[TextlikeNode] = nodes.emphasis,                    contnode: Node = None, env: BuildEnvironment = None) -> List[Node]:        delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+)'        delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+|\.\.\.)'         delims_re = re.compile(delims)         sub_targets = re.split(delims, target)


Question: autodoc: duplication warning on documenting aliased object Describe the bug autodoc: duplication warning on documenting aliased object To Reproduce Expected behavior No warning Your project N/A Screenshots N/A Environment info OS: Mac Python version: 3.9.4 Sphinx version: HEAD of 4.0.x Sphinx extensions: Extra tools: No Additional context No

docname: str     node_id: str     objtype: str    canonical: bool    aliased: bool   class ModuleEntry(NamedTuple):


Question: autodoc: duplication warning on documenting aliased object Describe the bug autodoc: duplication warning on documenting aliased object To Reproduce Expected behavior No warning Your project N/A Screenshots N/A Environment info OS: Mac Python version: 3.9.4 Sphinx version: HEAD of 4.0.x Sphinx extensions: Extra tools: No Additional context No

canonical_name = self.options.get('canonical')         if canonical_name:            domain.note_object(canonical_name, self.objtype, node_id, canonical=True,            domain.note_object(canonical_name, self.objtype, node_id, aliased=True,                                location=signode)          if 'noindexentry' not in self.options:


Question: autodoc: duplication warning on documenting aliased object Describe the bug autodoc: duplication warning on documenting aliased object To Reproduce Expected behavior No warning Your project N/A Screenshots N/A Environment info OS: Mac Python version: 3.9.4 Sphinx version: HEAD of 4.0.x Sphinx extensions: Extra tools: No Additional context No

return self.data.setdefault('objects', {})  # fullname -> ObjectEntry      def note_object(self, name: str, objtype: str, node_id: str,                    canonical: bool = False, location: Any = None) -> None:                    aliased: bool = False, location: Any = None) -> None:         """Note a python object for cross reference.          .. versionadded:: 2.1         """         if name in self.objects:             other = self.objects[name]            logger.warning(__('duplicate object description of %s, '                              'other instance in %s, use :noindex: for one of them'),                           name, other.docname, location=location)        self.objects[name] = ObjectEntry(self.env.docname, node_id, objtype, canonical)            if other.aliased and aliased is False:                # The original definition found. Override it!                pass            elif other.aliased is False and aliased:                # The original definition is already registered.                return            else:                # duplicated                logger.warning(__('duplicate object description of %s, '                                  'other instance in %s, use :noindex: for one of them'),                               name, other.docname, location=location)        self.objects[name] = ObjectEntry(self.env.docname, node_id, objtype, aliased)      @property     def modules(self) -> Dict[str, ModuleEntry]:


Question: autodoc: duplication warning on documenting aliased object Describe the bug autodoc: duplication warning on documenting aliased object To Reproduce Expected behavior No warning Your project N/A Screenshots N/A Environment info OS: Mac Python version: 3.9.4 Sphinx version: HEAD of 4.0.x Sphinx extensions: Extra tools: No Additional context No

yield (modname, modname, 'module', mod.docname, mod.node_id, 0)         for refname, obj in self.objects.items():             if obj.objtype != 'module':  # modules are already handled                if obj.canonical:                    # canonical names are not full-text searchable.                if obj.aliased:                    # aliased names are not full-text searchable.                     yield (refname, refname, obj.objtype, obj.docname, obj.node_id, -1)                 else:                     yield (refname, refname, obj.objtype, obj.docname, obj.node_id, 1)


Question: Omitting constructor signature from class header using I'm a bit surprised to see that (in the Python domain) will create a heading like which seems quite unintuitive to me, as it mixes two concepts: the declaration of "class Foo", with a constructor call "Foo(args)". How can I suppress the (automatic) addition of the constructor signature to the generated heading ? I actually want to document the constructor with an additional nested directive, and I also have an overloaded method, making the above all the more confusing. Am I missing or misunderstanding something ?

def __contains__(self, item: Any) -> bool:         return True <ins>    def append(self, item: Any) -> None:        pass  # nothing</ins>  class _Empty:     """A special value for :exclude-members: that never matches to any member."""


Question: Omitting constructor signature from class header using I'm a bit surprised to see that (in the Python domain) will create a heading like which seems quite unintuitive to me, as it mixes two concepts: the declaration of "class Foo", with a constructor call "Foo(args)". How can I suppress the (automatic) addition of the constructor signature to the generated heading ? I actually want to document the constructor with an additional nested directive, and I also have an overloaded method, making the above all the more confusing. Am I missing or misunderstanding something ?

def __init__(self, *args: Any) -> None:         super().__init__(*args)<ins>        if self.config.autodoc_class_signature == 'separated':            # show __init__() method            if self.options.special_members is None:                self.options['special-members'] = {'__new__', '__init__'}            else:                self.options.special_members.append('__new__')                self.options.special_members.append('__init__')</ins>         merge_members_option(self.options)      @classmethod


Question: Omitting constructor signature from class header using I'm a bit surprised to see that (in the Python domain) will create a heading like which seems quite unintuitive to me, as it mixes two concepts: the declaration of "class Foo", with a constructor call "Foo(args)". How can I suppress the (automatic) addition of the constructor signature to the generated heading ? I actually want to document the constructor with an additional nested directive, and I also have an overloaded method, making the above all the more confusing. Am I missing or misunderstanding something ?

def format_signature(self, **kwargs: Any) -> str:         if self.doc_as_attr:             return ''<ins>        if self.config.autodoc_class_signature == 'separated':            # do not show signatures            return ''</ins>          sig = super().format_signature()         sigs = []


Question: Omitting constructor signature from class header using I'm a bit surprised to see that (in the Python domain) will create a heading like which seems quite unintuitive to me, as it mixes two concepts: the declaration of "class Foo", with a constructor call "Foo(args)". How can I suppress the (automatic) addition of the constructor signature to the generated heading ? I actually want to document the constructor with an additional nested directive, and I also have an overloaded method, making the above all the more confusing. Am I missing or misunderstanding something ?

else:             return None <ins>    def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:        if self.objpath[-1] == '__init__':            docstring = getdoc(self.object, self.get_attr,                               self.config.autodoc_inherit_docstrings,                               self.parent, self.object_name)            if (docstring is not None and                (docstring == object.__init__.__doc__ or  # for pypy                 docstring.strip() == object.__init__.__doc__)):  # for !pypy                docstring = None            if docstring:                tab_width = self.directive.state.document.settings.tab_width                return [prepare_docstring(docstring, tabsize=tab_width)]            else:                return []        elif self.objpath[-1] == '__new__':            __new__ = self.get_attr(self.object, '__new__', None)            if __new__:                docstring = getdoc(__new__, self.get_attr,                                   self.config.autodoc_inherit_docstrings,                                   self.parent, self.object_name)                if (docstring is not None and                    (docstring == object.__new__.__doc__ or  # for pypy                     docstring.strip() == object.__new__.__doc__)):  # for !pypy                    docstring = None            if docstring:                tab_width = self.directive.state.document.settings.tab_width                return [prepare_docstring(docstring, tabsize=tab_width)]            else:                return []        else:            return super().get_doc()</ins>  class NonDataDescriptorMixin(DataDocumenterMixinBase):     """


Question: Omitting constructor signature from class header using I'm a bit surprised to see that (in the Python domain) will create a heading like which seems quite unintuitive to me, as it mixes two concepts: the declaration of "class Foo", with a constructor call "Foo(args)". How can I suppress the (automatic) addition of the constructor signature to the generated heading ? I actually want to document the constructor with an additional nested directive, and I also have an overloaded method, making the above all the more confusing. Am I missing or misunderstanding something ?

app.add_config_value('autoclass_content', 'class', True, ENUM('both', 'class', 'init'))     app.add_config_value('autodoc_member_order', 'alphabetical', True,                          ENUM('alphabetic', 'alphabetical', 'bysource', 'groupwise'))    app.add_config_value('autodoc_class_signature', 'mixed', True, ENUM('mixed', 'separated'))     app.add_config_value('autodoc_default_options', {}, True)     app.add_config_value('autodoc_docstring_signature', True, True)     app.add_config_value('autodoc_mock_imports', [], True)diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py-- a/sphinx/ext/autosummary/__init__.py++ b/sphinx/ext/autosummary/__init__.py


Question: Omitting constructor signature from class header using I'm a bit surprised to see that (in the Python domain) will create a heading like which seems quite unintuitive to me, as it mixes two concepts: the declaration of "class Foo", with a constructor call "Foo(args)". How can I suppress the (automatic) addition of the constructor signature to the generated heading ? I actually want to document the constructor with an additional nested directive, and I also have an overloaded method, making the above all the more confusing. Am I missing or misunderstanding something ?

document = Struct(settings=settings)         env = BuildEnvironment()         env.config = Config()<ins>        env.config.add('autodoc_class_signature', 'mixed', True, None)</ins>         state = Struct(document=document)         super().__init__(env, None, Options(), 0, state)


Question: Special member is not documented with automodule Describe the bug If I have a module which has a special attribute (starting with a double underscore) it will not be documented by automodule even if it's specified in :special-members:. According to my research it's because it's not identified as an attribute. If a non-special attribute is used, everything works fine. To Reproduce To execute the build I use Expected behavior The attribute should be documented. Environment info OS: Linux Python version: 3.7.1 Sphinx version: 3.5.4

# if isattr is True, the member is documented as an attribute             if member is INSTANCEATTR:                 isattr = True<ins>            elif (namespace, membername) in attr_docs:                isattr = True</ins>             else:                 isattr = False


Question: Special member is not documented with automodule Describe the bug If I have a module which has a special attribute (starting with a double underscore) it will not be documented by automodule even if it's specified in :special-members:. According to my research it's because it's not identified as an attribute. If a non-special attribute is used, everything works fine. To Reproduce To execute the build I use Expected behavior The attribute should be documented. Environment info OS: Linux Python version: 3.7.1 Sphinx version: 3.5.4

else:                     # keep documented attributes                     keep = True<del>                isattr = True</del>             elif want_all and isprivate:                 if has_doc or self.options.undoc_members:                     if self.options.private_members is None:


Question: Sphinx 4.0 finds more than one target for cross-reference Hello everyone, Describe the bug After upgrading to 4.0.0 we have discovered that existing code is raising a warning with . In 3.5.4 we did not see this warning To Reproduce I have set up a minimal reproduction repository here: Steps to reproduce the behavior: Output of the sphinx-build command: Expected behavior no warning appears Your project Environment info OS: Linux Python version: 3.9.4 Sphinx version: 4.0.0 Sphinx extensions: Additional context I have bisected the issue to be introduced by Thanks verry much

if not matches:             return None         elif len(matches) > 1:            logger.warning(__('more than one target found for cross-reference %r: %s'),                           target, ', '.join(match[0] for match in matches),                           type='ref', subtype='python', location=node)            canonicals = [m for m in matches if not m[1].aliased]            if len(canonicals) == 1:                matches = canonicals            else:                logger.warning(__('more than one target found for cross-reference %r: %s'),                               target, ', '.join(match[0] for match in matches),                               type='ref', subtype='python', location=node)         name, obj = matches[0]          if obj[2] == 'module':


Question: Inconsistent behaviour with type alias documentation (not overwriting all the default messages, just some) Describe the bug Hello, I have 3 muiltiline docstrings for type aliases (using the next-line documentation syntax). For 1 one them the docstring is correctly shown in the rendered HTML, but for 2 of them, the docstrings are ignored and the only thing shown is the text. I suppose this is related to , but I might be doing something wrong here (so if you could point me out in the correct direction that would be very good). To Reproduce The following is a reduced example of something happening in : a directory with : I run: the path adjustment in to the generated , and to the toctree in . opening in the browser should show the reported inconsistency. Expected behavior The docs should show the contents in the docstrings for all the type aliases instead of the the default text. Your project Screenshots ! Environment info OS: Win10 WSL: Python version: 3.6.9 Sphinx version: 3.1.2 Sphinx extensions: Additional context Possibly related to

def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:         if self.doc_as_attr:             # Don't show the docstring of the class when it is an alias.            return None            comment = self.get_variable_comment()            if comment:                return []            else:                return None          lines = getattr(self, '_new_docstrings', None)         if lines is not None:


Question: Inconsistent behaviour with type alias documentation (not overwriting all the default messages, just some) Describe the bug Hello, I have 3 muiltiline docstrings for type aliases (using the next-line documentation syntax). For 1 one them the docstring is correctly shown in the rendered HTML, but for 2 of them, the docstrings are ignored and the only thing shown is the text. I suppose this is related to , but I might be doing something wrong here (so if you could point me out in the correct direction that would be very good). To Reproduce The following is a reduced example of something happening in : a directory with : I run: the path adjustment in to the generated , and to the toctree in . opening in the browser should show the reported inconsistency. Expected behavior The docs should show the contents in the docstrings for all the type aliases instead of the the default text. Your project Screenshots ! Environment info OS: Win10 WSL: Python version: 3.6.9 Sphinx version: 3.1.2 Sphinx extensions: Additional context Possibly related to

tab_width = self.directive.state.document.settings.tab_width         return [prepare_docstring(docstring, ignore, tab_width) for docstring in docstrings]     def get_variable_comment(self) -> Optional[List[str]]:        try:            key = ('', '.'.join(self.objpath))            analyzer = ModuleAnalyzer.for_module(self.get_real_modname())            analyzer.analyze()            return list(self.analyzer.attr_docs.get(key, []))        except PycodeError:            return None     def add_content(self, more_content: Optional[StringList], no_docstring: bool = False                     ) -> None:        if self.doc_as_attr:        if self.doc_as_attr and not self.get_variable_comment():             try:                 more_content = StringList([_('alias of %s') % restify(self.object)], source='')             except AttributeError:


Question: Doc rendering is incorrect when :param has datatype dict(str,str) Describe the bug I have a parameter defined under docstring of a method as:- :param dict(str, str) opcmeta: (optional) Which is being incorrectly rendered in the generated docs as:- str) opcmeta (dict(str,) –(optional) To Reproduce Create any method with the docstring containg the above param Expected behavior The param should be rendered in the generated docs as:- opc_meta (dict(str,str)) – (optional) Your project Screenshots <img width="612" alt="Screen Shot 2021-05-12 at 12 30 50 PM" src="https://user-"<img width="681" alt="Screen Shot 2021-05-12 at 12 32 25 PM" src="https://user-"Environment info OS: Mac Python version: 3.9.0 Sphinx version: 4.0.1 Sphinx extensions: ["", "", "", "autodocsumm"] Extra tools: Browser Firefox. Additional context N/A

# also support syntax like ``:param type name:``             if typedesc.is_typed:                 try:                    argtype, argname = fieldarg.split(None, 1)                    argtype, argname = fieldarg.rsplit(None, 1)                 except ValueError:                     pass                 else:


Question: manmakesectiondirectory should not be enabled by default Enabling by default in breaks projects relying on the previous behavior. This is a serious problem for Linux distributions that will end up with misplaced and unusable man pages. Please consider keeping it disabled by default; the benefit of being able to use MANPATH in the output directory does not justify this kind of breakage. I also noticed that the current implementation generates paths like instead of . Only the latter can be used with MANPATH which appears to be the main motivation behind . Examples of breakage I've seen so far (and we've only had sphinx 4.0.x in Arch Linux for three days): does not expect the section subdirectory and results in man pages for built-in shell commands being installed to instead of and also fails to filter out , and which are meant to be installed to . copies the output directory to resulting in paths like (note the additional directory).

docsettings.section = section              if self.config.man_make_section_directory:                ensuredir(path.join(self.outdir, str(section)))                targetname = '%s/%s.%s' % (section, name, section)                dirname = 'man%s' % section                ensuredir(path.join(self.outdir, dirname))                targetname = '%s/%s.%s' % (dirname, name, section)             else:                 targetname = '%s.%s' % (name, section)


Question: New hook to customize base list I would like to change the formatting of the base list for classes. Specifially I would like to provide information about parameterized types (e.g. ]). See agronholm/sphinx-autodoc-typehints for how I want to use it. For that I need a new hook/event similar to the existing . I propose the signature . The first five arguments are exactly the same as for the existing events. The last one is the list of formatted strings generated in for the bases. It can be modified to change what is output. Alternatively, to provide even more freedom, the hook can return a string. This string is then inserted instead of the "Bases: ..." line. I can provide an implementation in a pull request, if you like the idea.

# add inheritance info, if wanted         if not self.doc_as_attr and self.options.show_inheritance:            sourcename = self.get_sourcename()            self.add_line('', sourcename)             if hasattr(self.object, '__orig_bases__') and len(self.object.__orig_bases__):                 # A subclass of generic types                 # refs: PEP-560 <https://www.python.org/dev/peps/pep-0560/>                bases = [restify(cls) for cls in self.object.__orig_bases__]                self.add_line('   ' + _('Bases: %s') % ', '.join(bases), sourcename)                bases = list(self.object.__orig_bases__)             elif hasattr(self.object, '__bases__') and len(self.object.__bases__):                 # A normal class                bases = [restify(cls) for cls in self.object.__bases__]                self.add_line('   ' + _('Bases: %s') % ', '.join(bases), sourcename)                bases = list(self.object.__bases__)            else:                bases = []            self.env.events.emit('autodoc-process-bases',                                 self.fullname, self.object, self.options, bases)            base_classes = [restify(cls) for cls in bases]            sourcename = self.get_sourcename()            self.add_line('', sourcename)            self.add_line('   ' + _('Bases: %s') % ', '.join(base_classes), sourcename)      def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]:         members = get_class_members(self.object, self.objpath, self.get_attr)


Question: New hook to customize base list I would like to change the formatting of the base list for classes. Specifially I would like to provide information about parameterized types (e.g. ]). See agronholm/sphinx-autodoc-typehints for how I want to use it. For that I need a new hook/event similar to the existing . I propose the signature . The first five arguments are exactly the same as for the existing events. The last one is the list of formatted strings generated in for the bases. It can be modified to change what is output. Alternatively, to provide even more freedom, the hook can return a string. This string is then inserted instead of the "Bases: ..." line. I can provide an implementation in a pull request, if you like the idea.

app.add_event('autodoc-process-docstring')     app.add_event('autodoc-process-signature')     app.add_event('autodoc-skip-member')<ins>    app.add_event('autodoc-process-bases')</ins>      app.connect('config-inited', migrate_autodoc_member_order, priority=800)


Question: Link checker should be able to prohibit unknown redirects Is your feature request related to a problem? Please describe. A lot of links become stale or move. Good websites will provide redirects to the correct new location or return an HTTP error code. Bad websites will redirect to an unrelated page or the root of the website. Preventing all redirects does not allow links to URLs like which redirects to It needs to be possible to allow these redirects but disallow others. Describe the solution you'd like It should be possible to prohibit unknown redirects by listing all of the allowed redirects as pairs of URLs. Describe alternatives you've considered Post-process by removing filenames and line numbers then sorting it and comparing it with known good output. Additional context A link to (which used to work) now redirects to Linkcheck allows this but the original link is not valid and needs to be updated to the article's new URL of Linkcheck should be able to report an error for this redirect.

except KeyError:                 text, color = ('with unknown code', purple)             linkstat['text'] = text            logger.info(color('redirect  ') + result.uri +                        color(' - ' + text + ' to ' + result.message))            if self.config.linkcheck_allowed_redirects:                logger.warning('redirect  ' + result.uri + ' - ' + text + ' to ' +                               result.message, location=(filename, result.lineno))            else:                logger.info(color('redirect  ') + result.uri +                            color(' - ' + text + ' to ' + result.message))             self.write_entry('redirected ' + text, result.docname, filename,                              result.lineno, result.uri + ' to ' + result.message)         else:


Question: Link checker should be able to prohibit unknown redirects Is your feature request related to a problem? Please describe. A lot of links become stale or move. Good websites will provide redirects to the correct new location or return an HTTP error code. Bad websites will redirect to an unrelated page or the root of the website. Preventing all redirects does not allow links to URLs like which redirects to It needs to be possible to allow these redirects but disallow others. Describe the solution you'd like It should be possible to prohibit unknown redirects by listing all of the allowed redirects as pairs of URLs. Describe alternatives you've considered Post-process by removing filenames and line numbers then sorting it and comparing it with known good output. Additional context A link to (which used to work) now redirects to Linkcheck allows this but the original link is not valid and needs to be updated to the article's new URL of Linkcheck should be able to report an error for this redirect.

new_url = response.url                 if anchor:                     new_url += '#' + anchor                # history contains any redirects, get last                if response.history:                if allowed_redirect(req_url, new_url):                    return 'working', '', 0                elif response.history:                    # history contains any redirects, get last                     code = response.history[-1].status_code                     return 'redirected', new_url, code                 else:                     return 'redirected', new_url, 0         def allowed_redirect(url: str, new_url: str) -> bool:            for from_url, to_url in self.config.linkcheck_allowed_redirects.items():                if from_url.match(url) and to_url.match(new_url):                    return True            return False         def check(docname: str) -> Tuple[str, str, int]:             # check for various conditions without bothering the network             if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'tel:')):


Question: Link checker should be able to prohibit unknown redirects Is your feature request related to a problem? Please describe. A lot of links become stale or move. Good websites will provide redirects to the correct new location or return an HTTP error code. Bad websites will redirect to an unrelated page or the root of the website. Preventing all redirects does not allow links to URLs like which redirects to It needs to be possible to allow these redirects but disallow others. Describe the solution you'd like It should be possible to prohibit unknown redirects by listing all of the allowed redirects as pairs of URLs. Describe alternatives you've considered Post-process by removing filenames and line numbers then sorting it and comparing it with known good output. Additional context A link to (which used to work) now redirects to Linkcheck allows this but the original link is not valid and needs to be updated to the article's new URL of Linkcheck should be able to report an error for this redirect.

return None  def compile_linkcheck_allowed_redirects(app: Sphinx, config: Config) -> None:    """Compile patterns in linkcheck_allowed_redirects to the regexp objects."""    for url, pattern in list(app.config.linkcheck_allowed_redirects.items()):        try:            app.config.linkcheck_allowed_redirects[re.compile(url)] = re.compile(pattern)        except re.error as exc:            logger.warning(__('Failed to compile regex in linkcheck_allowed_redirects: %r %s'),                           exc.pattern, exc.msg)        finally:            # Remove the original regexp-string            app.config.linkcheck_allowed_redirects.pop(url) def setup(app: Sphinx) -> Dict[str, Any]:     app.add_builder(CheckExternalLinksBuilder)     app.add_post_transform(HyperlinkCollector)      app.add_config_value('linkcheck_ignore', [], None)    app.add_config_value('linkcheck_allowed_redirects', {}, None)     app.add_config_value('linkcheck_auth', [], None)     app.add_config_value('linkcheck_request_headers', {}, None)     app.add_config_value('linkcheck_retries', 1, None)


Question: Link checker should be able to prohibit unknown redirects Is your feature request related to a problem? Please describe. A lot of links become stale or move. Good websites will provide redirects to the correct new location or return an HTTP error code. Bad websites will redirect to an unrelated page or the root of the website. Preventing all redirects does not allow links to URLs like which redirects to It needs to be possible to allow these redirects but disallow others. Describe the solution you'd like It should be possible to prohibit unknown redirects by listing all of the allowed redirects as pairs of URLs. Describe alternatives you've considered Post-process by removing filenames and line numbers then sorting it and comparing it with known good output. Additional context A link to (which used to work) now redirects to Linkcheck allows this but the original link is not valid and needs to be updated to the article's new URL of Linkcheck should be able to report an error for this redirect.

app.add_config_value('linkcheck_rate_limit_timeout', 300.0, None)      app.add_event('linkcheck-process-uri')<ins>    app.connect('config-inited', compile_linkcheck_allowed_redirects, priority=800)</ins>     app.connect('linkcheck-process-uri', rewrite_github_anchor)      return {


Question: Unknown node: : : : Run: OS: Linux Python version: 3.9.4 Sphinx version: 4.0.1 Sphinx extensions: , , This is similar to the issue that was fixed in . I think, that I've tracked the issue to the plugin. This plugin connects itself to events like this however, their implementation doesn't have the snippet, which eventually leads to the above error. I could submit this as a bug report to the author of , but I wanted to make sure, that this behaviour is intended. It seems to me like a potential antipattern. For example, the above snippet (with minor variations) is already duplicated internally in - - And any plugin that connects to the event must also now add this snippet (which is complicated by the fact that doesn't seem to be available in ). Do you think that maybe the value should be resolved when the event is created in ?

:license: BSD, see LICENSE for details. """ from typing import Any, Dict, List, Optional, Tuple, Type, castfrom typing import Any, Dict, List, Optional, Sequence, Tuple, Type, cast  from docutils import nodesfrom docutils.nodes import Elementfrom docutils.nodes import Element, Node  from sphinx import addnodes from sphinx.addnodes import pending_xref


Question: Unknown node: : : : Run: OS: Linux Python version: 3.9.4 Sphinx version: 4.0.1 Sphinx extensions: , , This is similar to the issue that was fixed in . I think, that I've tracked the issue to the plugin. This plugin connects itself to events like this however, their implementation doesn't have the snippet, which eventually leads to the above error. I could submit this as a bug report to the author of , but I wanted to make sure, that this behaviour is intended. It seems to me like a potential antipattern. For example, the above snippet (with minor variations) is already duplicated internally in - - And any plugin that connects to the event must also now add this snippet (which is complicated by the fact that doesn't seem to be available in ). Do you think that maybe the value should be resolved when the event is created in ?

logger = logging.getLogger(__name__) <del>if False:    # For type annotation    from docutils.nodes import Node</del>  class SphinxPostTransform(SphinxTransform):     """A base class of post-transforms.


Question: Unknown node: : : : Run: OS: Linux Python version: 3.9.4 Sphinx version: 4.0.1 Sphinx extensions: , , This is similar to the issue that was fixed in . I think, that I've tracked the issue to the plugin. This plugin connects itself to events like this however, their implementation doesn't have the snippet, which eventually leads to the above error. I could submit this as a bug report to the author of , but I wanted to make sure, that this behaviour is intended. It seems to me like a potential antipattern. For example, the above snippet (with minor variations) is already duplicated internally in - - And any plugin that connects to the event must also now add this snippet (which is complicated by the fact that doesn't seem to be available in ). Do you think that maybe the value should be resolved when the event is created in ?

def run(self, **kwargs: Any) -> None:         for node in self.document.traverse(addnodes.pending_xref):            contnode = cast(nodes.TextElement, node[0].deepcopy())            content = self.find_pending_xref_condition(node, ("resolved", "*"))            if content:                contnode = cast(Element, content[0].deepcopy())            else:                contnode = cast(Element, node[0].deepcopy())             newnode = None              typ = node['reftype']