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 ?

else:                 newnodes = [contnode]                 if newnode is None and isinstance(node[0], addnodes.pending_xref_condition):                    matched = find_pending_xref_condition(node, "*")                    matched = self.find_pending_xref_condition(node, ("*",))                     if matched:                        newnodes = matched.children                        newnodes = matched                     else:                         logger.warning(__('Could not determine the fallback text for the '                                           'cross-reference. Might be a bug.'), location=node)


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 ?

msg = __('%r reference target not found: %s') % (typ, target)         logger.warning(msg, location=node, type='ref', subtype=typ) <ins>    def find_pending_xref_condition(self, node: pending_xref, conditions: Sequence[str]                                    ) -> Optional[List[Node]]:        for condition in conditions:            matched = find_pending_xref_condition(node, condition)            if matched:                return matched.children        else:            return None</ins>  class OnlyNodeTransform(SphinxPostTransform):     default_priority = 50


Question: [RFE] Support union types specification using | (vertical bar/pipe) Please add a support for specifying multiple types acceptable for a parameter/attribute/variable. Use case: Imagine that there is a function that accepts both and . The docstring would look like: Such a syntax is already supported by e.g. .

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+|\s*\|\s*|\.\.\.)'         delims_re = re.compile(delims)         sub_targets = re.split(delims, target)


Question: Linkchecker croaks on specific anchors of GitHub-rendered reStructuredText documents Dear Sphinx developers, first things first: Thanks a stack for your paramount work on Sphinx. You already saved many souls of people writing technical documentation and probably also beyond this audience. We just observed a minor woe with Sphinx' linkchecker we wanted to share with you. We really like that the linkchecker is able to check anchors within HTML documents as contributed by on behalf of . With kind regards, Andreas. Describe the bug We had the link [1] in our documentation, and, maybe after upgrading to more recent versions of Sphinx, the linkchecker suddenly started croaking on that. After changing it to [2], it worked again. When inspecting the source code of the respective HTML page, you can clearly see that the anchor name defined by is technically correct. However, it apparently has worked before by referencing . So, we are wondering if something changed on GitHub's reStructuredText renderer or even Browsers interpreting the HTML link anchors differently. When invoking those links [1,2] in the Browser, actually both work, including navigation to the appropriate place within the page. Funny, hm? [1] [2] Expected behavior Technically, from the perspective we know our way around HTML, the behavior is probably the right thing and correct. However, as we can see, something might have been changed on the HTML standard that Browsers are capable of interpreting different styles of defining link anchors. So, it might be worth to revisit this space and maybe improve the linkchecker implementation on those aspects. Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Firefox: 86.0

from threading import Thread from typing import (Any, Dict, Generator, List, NamedTuple, Optional, Pattern, Set, Tuple,                     Union, cast)from urllib.parse import unquote, urlparsefrom urllib.parse import unquote, urlparse, urlunparse  from docutils import nodes from docutils.nodes import Element


Question: Linkchecker croaks on specific anchors of GitHub-rendered reStructuredText documents Dear Sphinx developers, first things first: Thanks a stack for your paramount work on Sphinx. You already saved many souls of people writing technical documentation and probably also beyond this audience. We just observed a minor woe with Sphinx' linkchecker we wanted to share with you. We really like that the linkchecker is able to check anchors within HTML documents as contributed by on behalf of . With kind regards, Andreas. Describe the bug We had the link [1] in our documentation, and, maybe after upgrading to more recent versions of Sphinx, the linkchecker suddenly started croaking on that. After changing it to [2], it worked again. When inspecting the source code of the respective HTML page, you can clearly see that the anchor name defined by is technically correct. However, it apparently has worked before by referencing . So, we are wondering if something changed on GitHub's reStructuredText renderer or even Browsers interpreting the HTML link anchors differently. When invoking those links [1,2] in the Browser, actually both work, including navigation to the appropriate place within the page. Funny, hm? [1] [2] Expected behavior Technically, from the perspective we know our way around HTML, the behavior is probably the right thing and correct. However, as we can see, something might have been changed on the HTML standard that Browsers are capable of interpreting different styles of defining link anchors. So, it might be worth to revisit this space and maybe improve the linkchecker implementation on those aspects. Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Firefox: 86.0

if 'refuri' not in refnode:                 continue             uri = refnode['refuri']<ins>            newuri = self.app.emit_firstresult('linkcheck-process-uri', uri)            if newuri:                uri = newuri</ins>             lineno = get_node_line(refnode)             uri_info = Hyperlink(uri, self.env.docname, lineno)             if uri not in hyperlinks:


Question: Linkchecker croaks on specific anchors of GitHub-rendered reStructuredText documents Dear Sphinx developers, first things first: Thanks a stack for your paramount work on Sphinx. You already saved many souls of people writing technical documentation and probably also beyond this audience. We just observed a minor woe with Sphinx' linkchecker we wanted to share with you. We really like that the linkchecker is able to check anchors within HTML documents as contributed by on behalf of . With kind regards, Andreas. Describe the bug We had the link [1] in our documentation, and, maybe after upgrading to more recent versions of Sphinx, the linkchecker suddenly started croaking on that. After changing it to [2], it worked again. When inspecting the source code of the respective HTML page, you can clearly see that the anchor name defined by is technically correct. However, it apparently has worked before by referencing . So, we are wondering if something changed on GitHub's reStructuredText renderer or even Browsers interpreting the HTML link anchors differently. When invoking those links [1,2] in the Browser, actually both work, including navigation to the appropriate place within the page. Funny, hm? [1] [2] Expected behavior Technically, from the perspective we know our way around HTML, the behavior is probably the right thing and correct. However, as we can see, something might have been changed on the HTML standard that Browsers are capable of interpreting different styles of defining link anchors. So, it might be worth to revisit this space and maybe improve the linkchecker implementation on those aspects. Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Firefox: 86.0

for imgnode in self.document.traverse(nodes.image):             uri = imgnode['candidates'].get('?')             if uri and '://' in uri:                newuri = self.app.emit_firstresult('linkcheck-process-uri', uri)                if newuri:                    uri = newuri                 lineno = get_node_line(imgnode)                 uri_info = Hyperlink(uri, self.env.docname, lineno)                 if uri not in hyperlinks:                     hyperlinks[uri] = uri_info  def rewrite_github_anchor(app: Sphinx, uri: str) -> Optional[str]:    """Rewrite anchor name of the hyperlink to github.com    The hyperlink anchors in github.com are dynamically generated.  This rewrites    them before checking and makes them comparable.    """    parsed = urlparse(uri)    if parsed.hostname == "github.com" and parsed.fragment:        prefixed = parsed.fragment.startswith('user-content-')        if not prefixed:            fragment = f'user-content-{parsed.fragment}'            return urlunparse(parsed._replace(fragment=fragment))    return None def setup(app: Sphinx) -> Dict[str, Any]:     app.add_builder(CheckExternalLinksBuilder)     app.add_post_transform(HyperlinkCollector)


Question: Linkchecker croaks on specific anchors of GitHub-rendered reStructuredText documents Dear Sphinx developers, first things first: Thanks a stack for your paramount work on Sphinx. You already saved many souls of people writing technical documentation and probably also beyond this audience. We just observed a minor woe with Sphinx' linkchecker we wanted to share with you. We really like that the linkchecker is able to check anchors within HTML documents as contributed by on behalf of . With kind regards, Andreas. Describe the bug We had the link [1] in our documentation, and, maybe after upgrading to more recent versions of Sphinx, the linkchecker suddenly started croaking on that. After changing it to [2], it worked again. When inspecting the source code of the respective HTML page, you can clearly see that the anchor name defined by is technically correct. However, it apparently has worked before by referencing . So, we are wondering if something changed on GitHub's reStructuredText renderer or even Browsers interpreting the HTML link anchors differently. When invoking those links [1,2] in the Browser, actually both work, including navigation to the appropriate place within the page. Funny, hm? [1] [2] Expected behavior Technically, from the perspective we know our way around HTML, the behavior is probably the right thing and correct. However, as we can see, something might have been changed on the HTML standard that Browsers are capable of interpreting different styles of defining link anchors. So, it might be worth to revisit this space and maybe improve the linkchecker implementation on those aspects. Environment info OS: Linux Python version: 3.9.2 Sphinx version: 3.5.2 Firefox: 86.0

app.add_config_value('linkcheck_anchors_ignore', ["^!"], None)     app.add_config_value('linkcheck_rate_limit_timeout', 300.0, None) <ins>    app.add_event('linkcheck-process-uri')    app.connect('linkcheck-process-uri', rewrite_github_anchor)</ins>     return {         'version': 'builtin',         'parallel_read_safe': True,


Question: Building autodocs for derived classes produces invalid warnings Describe the bug Generating API docs using the autodoc extensions, when a base class has doc strings in the constructor as well as in the class definition, and the autoclasscontent feature is set to "both", produces superfluous warnings when parsing derived classes with overloaded constructors with no doc strings on them. To Reproduce a base class with a constructor, and provide both a class doc string and a constructor doc string, something like this: a derived class that has an overloaded constructor, with no doc string, something like this: the auto content option in Sphinx to combine the class doc string and constructor doc strings together (ie: in the script) to generate the docs using the apidoc extension (ie: when using , just run ) Expected behavior Expected behavior: the API docs for both the base and derived classes should be generated without warnings. Actual behavior: docs for the base class generate correctly, but docs for the derived class produce the following warning "docstring of sample.MyDerived: WARNING: Unexpected indentation." Environment info OS: MacOS 11.3.1 (reproducible on several other Linux / Mac systems) Python version: 3.6.8 (reproducible on several newer versions as well) Sphinx version: 4.0.1 (reproducible on versions as far back as v2.2.0) Sphinx extensions: , Extra tools: (optional)

__init__ = self.get_attr(self.object, '__init__', None)             initdocstring = getdoc(__init__, self.get_attr,                                    self.config.autodoc_inherit_docstrings,                                   self.parent, self.object_name)                                   self.object, '__init__')             # for new-style classes, no __init__ means default __init__             if (initdocstring is not None and                 (initdocstring == object.__init__.__doc__ or  # for pypy


Question: Building autodocs for derived classes produces invalid warnings Describe the bug Generating API docs using the autodoc extensions, when a base class has doc strings in the constructor as well as in the class definition, and the autoclasscontent feature is set to "both", produces superfluous warnings when parsing derived classes with overloaded constructors with no doc strings on them. To Reproduce a base class with a constructor, and provide both a class doc string and a constructor doc string, something like this: a derived class that has an overloaded constructor, with no doc string, something like this: the auto content option in Sphinx to combine the class doc string and constructor doc strings together (ie: in the script) to generate the docs using the apidoc extension (ie: when using , just run ) Expected behavior Expected behavior: the API docs for both the base and derived classes should be generated without warnings. Actual behavior: docs for the base class generate correctly, but docs for the derived class produce the following warning "docstring of sample.MyDerived: WARNING: Unexpected indentation." Environment info OS: MacOS 11.3.1 (reproducible on several other Linux / Mac systems) Python version: 3.6.8 (reproducible on several newer versions as well) Sphinx version: 4.0.1 (reproducible on versions as far back as v2.2.0) Sphinx extensions: , Extra tools: (optional)

__new__ = self.get_attr(self.object, '__new__', None)                 initdocstring = getdoc(__new__, self.get_attr,                                        self.config.autodoc_inherit_docstrings,                                       self.parent, self.object_name)                                       self.object, '__new__')                 # for new-style classes, no __new__ means default __new__                 if (initdocstring is not None and                     (initdocstring == object.__new__.__doc__ or  # for pypydiff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py-- a/sphinx/util/inspect.py++ b/sphinx/util/inspect.py


Question: Building autodocs for derived classes produces invalid warnings Describe the bug Generating API docs using the autodoc extensions, when a base class has doc strings in the constructor as well as in the class definition, and the autoclasscontent feature is set to "both", produces superfluous warnings when parsing derived classes with overloaded constructors with no doc strings on them. To Reproduce a base class with a constructor, and provide both a class doc string and a constructor doc string, something like this: a derived class that has an overloaded constructor, with no doc string, something like this: the auto content option in Sphinx to combine the class doc string and constructor doc strings together (ie: in the script) to generate the docs using the apidoc extension (ie: when using , just run ) Expected behavior Expected behavior: the API docs for both the base and derived classes should be generated without warnings. Actual behavior: docs for the base class generate correctly, but docs for the derived class produce the following warning "docstring of sample.MyDerived: WARNING: Unexpected indentation." Environment info OS: MacOS 11.3.1 (reproducible on several other Linux / Mac systems) Python version: 3.6.8 (reproducible on several newer versions as well) Sphinx version: 4.0.1 (reproducible on versions as far back as v2.2.0) Sphinx extensions: , Extra tools: (optional)

if ispartial(obj) and doc == obj.__class__.__doc__:         return getdoc(obj.func)     elif doc is None and allow_inherited:        doc = inspect.getdoc(obj)        if doc is None and cls and name:            # inspect.getdoc() does not support some kind of inherited and decorated methods.            # This tries to obtain the docstring from super classes.            for basecls in getattr(cls, '__mro__', []):        if cls and name:            # Check a docstring of the attribute or method from super classes.            for basecls in getmro(cls):                 meth = safe_getattr(basecls, name, None)                 if meth is not None:                    doc = inspect.getdoc(meth)                    if doc:                    doc = attrgetter(meth, '__doc__', None)                    if doc is not None:                         break             if doc is None:                # retry using `inspect.getdoc()`                for basecls in getmro(cls):                    meth = safe_getattr(basecls, name, None)                    if meth is not None:                        doc = inspect.getdoc(meth)                        if doc is not None:                            break        if doc is None:            doc = inspect.getdoc(obj)     return doc


Question: Python Enum values (used to show default values in function signatures) are rendered ugly. Python Enum values (used to show default values in function signatures) are rendered ugly. To Reproduce I made a minimal example to show the issue: Expected behavior I would hope the signature rendered as: uglyenumfunc(e: uglyenum.MyEnum = MyEnum.ValueA) → None Unfortunately, it renders as: uglyenumfunc(e: ugly_enum.MyEnum = <MyEnum.ValueA: 10) → None Environment info Python version: 3.9.5 Sphinx version: 4.0.2 Sphinx extensions: autodoc

(object_description(key), object_description(object[key]))                      for key in sorted_keys)             return "{%s}" % ", ".join(items)    if isinstance(object, set):    elif isinstance(object, set):         try:             sorted_values = sorted(object)         except TypeError:             pass  # Cannot sort set values, fall back to generic repr         else:             return "{%s}" % ", ".join(object_description(x) for x in sorted_values)    if isinstance(object, frozenset):    elif isinstance(object, frozenset):         try:             sorted_values = sorted(object)         except TypeError:


Question: Python Enum values (used to show default values in function signatures) are rendered ugly. Python Enum values (used to show default values in function signatures) are rendered ugly. To Reproduce I made a minimal example to show the issue: Expected behavior I would hope the signature rendered as: uglyenumfunc(e: uglyenum.MyEnum = MyEnum.ValueA) → None Unfortunately, it renders as: uglyenumfunc(e: ugly_enum.MyEnum = <MyEnum.ValueA: 10) → None Environment info Python version: 3.9.5 Sphinx version: 4.0.2 Sphinx extensions: autodoc

else:             return "frozenset({%s})" % ", ".join(object_description(x)                                                  for x in sorted_values)<ins>    elif isinstance(object, enum.Enum):        return "%s.%s" % (object.__class__.__name__, object.name)</ins>     try:         s = repr(object)     except Exception as exc:


Question: pythonuseunqualifiedtypenames does not work on function descriptions Describe the bug When combining the new configuration with , the type names are not shortened even though links are created. To Reproduce Here's a minimal project using Sphinx 4.0.2 on Python 3.9: This produces documentation looking like this: ! Expected behavior I'd expect the link to be shortened to like it is when .

for node in result.traverse(nodes.Text):                 node.parent[node.parent.index(node)] = nodes.Text(text)                 break<ins>        elif isinstance(result, pending_xref) and env.config.python_use_unqualified_type_names:            children = result.children            result.clear()            shortname = target.split('.')[-1]            textnode = innernode('', shortname)            contnodes = [pending_xref_condition('', '', textnode, condition='resolved'),                         pending_xref_condition('', '', *children, condition='*')]            result.extend(contnodes)</ins>         return result      def make_xrefs(self, rolename: str, domain: str, target: str,


Question: Linkcheck Reports Broken Link when Remote Server Closes on HEAD Request Describe the bug Running on a document that contains an external link to a website may report the link is broken when a web browser may successfully open the link. Specifically, if the website closes its connection when receiving the request method, then will receive a exception, which bypasses the logic that would otherwise have it make an request. A specific example of a website exhibiting this behaviour is To Reproduce Steps to reproduce the behaviour: Observe linkcheck reporting a broken link: Open in your browser Click "a link to the US Patent Website" Observe the link opening and rendering normally Expected behavior If a link is valid, and the website is returning valid content for an request, should not report the link as . Internally, in , if a call to raises a exception, it should attempt a just like it does with and . Your project Environment info OS: (but this does not appear to be OS-dependent) Python version: and Sphinx version: and Sphinx extensions: none Extra tools: any common web browser Additional context Using , we can see that this particular website closes connections when receiving : Observe that this returns the expected HTML content Observe that this fails to return any content from the server

from docutils import nodes from docutils.nodes import Element from requests import Responsefrom requests.exceptions import HTTPError, TooManyRedirectsfrom requests.exceptions import ConnectionError, HTTPError, TooManyRedirects  from sphinx.application import Sphinx from sphinx.builders.dummy import DummyBuilder


Question: Linkcheck Reports Broken Link when Remote Server Closes on HEAD Request Describe the bug Running on a document that contains an external link to a website may report the link is broken when a web browser may successfully open the link. Specifically, if the website closes its connection when receiving the request method, then will receive a exception, which bypasses the logic that would otherwise have it make an request. A specific example of a website exhibiting this behaviour is To Reproduce Steps to reproduce the behaviour: Observe linkcheck reporting a broken link: Open in your browser Click "a link to the US Patent Website" Observe the link opening and rendering normally Expected behavior If a link is valid, and the website is returning valid content for an request, should not report the link as . Internally, in , if a call to raises a exception, it should attempt a just like it does with and . Your project Environment info OS: (but this does not appear to be OS-dependent) Python version: and Sphinx version: and Sphinx extensions: none Extra tools: any common web browser Additional context Using , we can see that this particular website closes connections when receiving : Observe that this returns the expected HTML content Observe that this fails to return any content from the server

config=self.config, auth=auth_info,                                                  **kwargs)                         response.raise_for_status()                    except (HTTPError, TooManyRedirects) as err:                    # Servers drop the connection on HEAD requests, causing                    # ConnectionError.                    except (ConnectionError, HTTPError, TooManyRedirects) as err:                         if isinstance(err, HTTPError) and err.response.status_code == 429:                             raise                         # retry with GET request if that fails, some servers


Question: with existing doesn't exit easily Describe the bug I've attached a screenshot in the screenshots section which I think explains the bug better. I'm running in a folder with a already existing. It says "Please enter a new root path name (or just Enter to exit)". However, upon pressing 'Enter' it returns an error message "Please enter a valid path name". To Reproduce Steps to reproduce the behavior: Expected behavior After pressing Enter, sphinx-quickstart exits. Your project n/a Screenshots ! I press Enter for the first prompt. Environment info OS: Ubuntu 20.04 Python version: Python 3.8.5 Sphinx version: sphinx-build 3.2.1 Sphinx extensions: none Extra tools: none Additional context I had a quick search but couldn't find any similar existing issues. Sorry if this is a duplicate.

return x  <ins>def is_path_or_empty(x: str) -> str:    if x == '':        return x    return is_path(x)</ins> def allow_empty(x: str) -> str:     return x


Question: with existing doesn't exit easily Describe the bug I've attached a screenshot in the screenshots section which I think explains the bug better. I'm running in a folder with a already existing. It says "Please enter a new root path name (or just Enter to exit)". However, upon pressing 'Enter' it returns an error message "Please enter a valid path name". To Reproduce Steps to reproduce the behavior: Expected behavior After pressing Enter, sphinx-quickstart exits. Your project n/a Screenshots ! I press Enter for the first prompt. Environment info OS: Ubuntu 20.04 Python version: Python 3.8.5 Sphinx version: sphinx-build 3.2.1 Sphinx extensions: none Extra tools: none Additional context I had a quick search but couldn't find any similar existing issues. Sorry if this is a duplicate.

print(__('sphinx-quickstart will not overwrite existing Sphinx projects.'))         print()         d['path'] = do_prompt(__('Please enter a new root path (or just Enter to exit)'),                              '', is_path)                              '', is_path_or_empty)         if not d['path']:             sys.exit(1)


Question: Man page using :samp: with braces - font doesn't reset There are issues with the man page rendering when using :samp: The font change doesn't reset after the closure of the samp but runs onto subsequent lines until certain 'resetting' elements are encountered, such as a bullet, heading and probably others I haven't tested for. :samp: is ok. HTML and Latex (pdf) formats are also unaffected by this issue. MWE included with screen shot. Text that should be plain. A bullet that should be plain. And back to normal. :samp: More text that should be plain. A bullet that should be plain. And back to normal. :samp: All ok on this line. !

for node in self.document.traverse(matcher):  # type: TextElement             if any(matcher(subnode) for subnode in node):                 pos = node.parent.index(node)                for subnode in reversed(node[1:]):                for subnode in reversed(list(node)):                     node.remove(subnode)                     if matcher(subnode):                         node.parent.insert(pos + 1, subnode)                     else:                         newnode = node.__class__('', '', subnode, **node.attributes)                         node.parent.insert(pos + 1, newnode)                # move node if all children became siblings of the node                if not len(node):                    node.parent.remove(node)   class ManualPageTranslator(SphinxTranslator, BaseTranslator):


Question: 1-element tuple rendered incorrectly Describe the bug This is a followup to which has been addressed in . However the special case of a 1-element tuple is still not handled correctly. is rendered as , but should keep the trailing comma. To Reproduce Add a testcase at

return "%s %s" % (self.visit(node.op), self.visit(node.operand))      def visit_Tuple(self, node: ast.Tuple) -> str:        if node.elts:            return "(" + ", ".join(self.visit(e) for e in node.elts) + ")"        else:        if len(node.elts) == 0:             return "()"        elif len(node.elts) == 1:            return "(%s,)" % self.visit(node.elts[0])        else:            return "(" + ", ".join(self.visit(e) for e in node.elts) + ")"      if sys.version_info < (3, 8):         # these ast nodes were deprecated in python 3.8


Question: Autodoc still using typehint types in properties Describe the bug Despite being set to , properties have type hints rendered in the output. To Reproduce Steps to reproduce the behavior. Download the zip below and go to then run Expected behavior No type hints in the output. Your project Screenshots ! Environment info OS: Windows 10 Python version: 3.9.2 Sphinx version: 4.0.2 Sphinx extensions: Extra tools: N/A Additional context Issue discovered in a real project (edit: I removed it using CSS).

self.add_line('   :annotation: %s' % self.options.annotation,                           sourcename)         else:            # obtain annotation for this data            annotations = get_type_hints(self.parent, None, self.config.autodoc_type_aliases)            if self.objpath[-1] in annotations:                objrepr = stringify_typehint(annotations.get(self.objpath[-1]))                self.add_line('   :type: ' + objrepr, sourcename)            if self.config.autodoc_typehints != 'none':                # obtain annotation for this data                annotations = get_type_hints(self.parent, None,                                             self.config.autodoc_type_aliases)                if self.objpath[-1] in annotations:                    objrepr = stringify_typehint(annotations.get(self.objpath[-1]))                    self.add_line('   :type: ' + objrepr, sourcename)              try:                 if self.options.no_value or self.should_suppress_value_header():


Question: Autodoc still using typehint types in properties Describe the bug Despite being set to , properties have type hints rendered in the output. To Reproduce Steps to reproduce the behavior. Download the zip below and go to then run Expected behavior No type hints in the output. Your project Screenshots ! Environment info OS: Windows 10 Python version: 3.9.2 Sphinx version: 4.0.2 Sphinx extensions: Extra tools: N/A Additional context Issue discovered in a real project (edit: I removed it using CSS).

elif self.options.annotation:             self.add_line('   :annotation: %s' % self.options.annotation, sourcename)         else:            # obtain type annotation for this attribute            annotations = get_type_hints(self.parent, None, self.config.autodoc_type_aliases)            if self.objpath[-1] in annotations:                objrepr = stringify_typehint(annotations.get(self.objpath[-1]))                self.add_line('   :type: ' + objrepr, sourcename)            if self.config.autodoc_typehints != 'none':                # obtain type annotation for this attribute                annotations = get_type_hints(self.parent, None,                                             self.config.autodoc_type_aliases)                if self.objpath[-1] in annotations:                    objrepr = stringify_typehint(annotations.get(self.objpath[-1]))                    self.add_line('   :type: ' + objrepr, sourcename)              try:                 if self.options.no_value or self.should_suppress_value_header():


Question: Autodoc still using typehint types in properties Describe the bug Despite being set to , properties have type hints rendered in the output. To Reproduce Steps to reproduce the behavior. Download the zip below and go to then run Expected behavior No type hints in the output. Your project Screenshots ! Environment info OS: Windows 10 Python version: 3.9.2 Sphinx version: 4.0.2 Sphinx extensions: Extra tools: N/A Additional context Issue discovered in a real project (edit: I removed it using CSS).

if inspect.isabstractmethod(self.object):             self.add_line('   :abstractmethod:', sourcename)         if safe_getattr(self.object, 'fget', None):        if safe_getattr(self.object, 'fget', None) and self.config.autodoc_typehints != 'none':             try:                 signature = inspect.signature(self.object.fget,                                               type_aliases=self.config.autodoc_type_aliases)


Question: Add an option to not use intersphinx references as a fallback That intersphinx references are used as fallbacks if a reference is not available in a project recently caused us a problem. We have a site () which is the latest build of . We use intersphinx as follows, so we can link to the latest documentation in some sections: Our docs included a label () so this reference was available on . This label was removed on a branch, along with one of the two references to this label. In this case we would expect that building the branch would fail, as there is a reference to a label which doesn't exist. Unexpectedly, the branch built successfully, because the label was found in as a fall back when it was not found locally. The branch was merged, and then later, when changed (because was built again) builds stopped working because there was a reference to a non-existent label. It would be good to have an option to not fall back, maybe something like .

import sys import time from os import pathfrom typing import IO, Any, Dict, List, Tuplefrom typing import IO, Any, Dict, List, Optional, Tuple from urllib.parse import urlsplit, urlunsplit  from docutils import nodesfrom docutils.nodes import TextElementfrom docutils.nodes import Element, TextElement from docutils.utils import relative_path  import sphinx


Question: Add an option to not use intersphinx references as a fallback That intersphinx references are used as fallbacks if a reference is not available in a project recently caused us a problem. We have a site () which is the latest build of . We use intersphinx as follows, so we can link to the latest documentation in some sections: Our docs included a label () so this reference was available on . This label was removed on a branch, along with one of the two references to this label. In this case we would expect that building the branch would fail, as there is a reference to a label which doesn't exist. Unexpectedly, the branch built successfully, because the label was found in as a fall back when it was not found locally. The branch was merged, and then later, when changed (because was built again) builds stopped working because there was a reference to a non-existent label. It would be good to have an option to not fall back, maybe something like .

from sphinx.application import Sphinx from sphinx.builders.html import INVENTORY_FILENAME from sphinx.config import Configfrom sphinx.domains import Domain from sphinx.environment import BuildEnvironment from sphinx.locale import _, __ from sphinx.util import logging, requests from sphinx.util.inventory import InventoryFilefrom sphinx.util.typing import Inventoryfrom sphinx.util.typing import Inventory, InventoryItem  logger = logging.getLogger(__name__)


Question: Add an option to not use intersphinx references as a fallback That intersphinx references are used as fallbacks if a reference is not available in a project recently caused us a problem. We have a site () which is the latest build of . We use intersphinx as follows, so we can link to the latest documentation in some sections: Our docs included a label () so this reference was available on . This label was removed on a branch, along with one of the two references to this label. In this case we would expect that building the branch would fail, as there is a reference to a label which doesn't exist. Unexpectedly, the branch built successfully, because the label was found in as a fall back when it was not found locally. The branch was merged, and then later, when changed (because was built again) builds stopped working because there was a reference to a non-existent label. It would be good to have an option to not fall back, maybe something like .

inventories.main_inventory.setdefault(type, {}).update(objects)  def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,                      contnode: TextElement) -> nodes.reference:    """Attempt to resolve a missing reference via intersphinx references."""    target = node['reftarget']    inventories = InventoryAdapter(env)    objtypes: List[str] = None    if node['reftype'] == 'any':        # we search anything!        objtypes = ['%s:%s' % (domain.name, objtype)                    for domain in env.domains.values()                    for objtype in domain.object_types]        domain = Nonedef _create_element_from_result(domain: Domain, inv_name: Optional[str],                                data: InventoryItem,                                node: pending_xref, contnode: TextElement) -> Element:    proj, version, uri, dispname = data    if '://' not in uri and node.get('refdoc'):        # get correct path in case of subdirectories        uri = path.join(relative_path(node['refdoc'], '.'), uri)    if version:        reftitle = _('(in %s v%s)') % (proj, version)     else:        domain = node.get('refdomain')        if not domain:        reftitle = _('(in %s)') % (proj,)    newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle)    if node.get('refexplicit'):        # use whatever title was given        newnode.append(contnode)    elif dispname == '-' or \            (domain.name == 'std' and node['reftype'] == 'keyword'):        # use whatever title was given, but strip prefix        title = contnode.astext()        if inv_name is not None and title.startswith(inv_name + ':'):            newnode.append(contnode.__class__(title[len(inv_name) + 1:],                                              title[len(inv_name) + 1:]))        else:            newnode.append(contnode)    else:        # else use the given display name (used for :ref:)        newnode.append(contnode.__class__(dispname, dispname))    return newnodedef _resolve_reference_in_domain_by_target(        inv_name: Optional[str], inventory: Inventory,        domain: Domain, objtypes: List[str],        target: str,        node: pending_xref, contnode: TextElement) -> Optional[Element]:    for objtype in objtypes:        if objtype not in inventory:            # Continue if there's nothing of this kind in the inventory            continue        if target in inventory[objtype]:            # Case sensitive match, use it            data = inventory[objtype][target]        elif objtype == 'std:term':            # Check for potential case insensitive matches for terms only            target_lower = target.lower()            insensitive_matches = list(filter(lambda k: k.lower() == target_lower,                                              inventory[objtype].keys()))            if insensitive_matches:                data = inventory[objtype][insensitive_matches[0]]            else:                # No case insensitive match either, continue to the next candidate                continue        else:            # Could reach here if we're not a term but have a case insensitive match.            # This is a fix for terms specifically, but potentially should apply to            # other types.            continue        return _create_element_from_result(domain, inv_name, data, node, contnode)    return Nonedef _resolve_reference_in_domain(env: BuildEnvironment,                                 inv_name: Optional[str], inventory: Inventory,                                 honor_disabled_refs: bool,                                 domain: Domain, objtypes: List[str],                                 node: pending_xref, contnode: TextElement                                 ) -> Optional[Element]:    # we adjust the object types for backwards compatibility    if domain.name == 'std' and 'cmdoption' in objtypes:        # until Sphinx-1.6, cmdoptions are stored as std:option        objtypes.append('option')    if domain.name == 'py' and 'attribute' in objtypes:        # Since Sphinx-2.1, properties are stored as py:method        objtypes.append('method')    # the inventory contains domain:type as objtype    objtypes = ["{}:{}".format(domain.name, t) for t in objtypes]    # now that the objtypes list is complete we can remove the disabled ones    if honor_disabled_refs:        disabled = env.config.intersphinx_disabled_reftypes        objtypes = [o for o in objtypes if o not in disabled]    # without qualification    res = _resolve_reference_in_domain_by_target(inv_name, inventory, domain, objtypes,                                                 node['reftarget'], node, contnode)    if res is not None:        return res    # try with qualification of the current scope instead    full_qualified_name = domain.get_full_qualified_name(node)    if full_qualified_name is None:        return None    return _resolve_reference_in_domain_by_target(inv_name, inventory, domain, objtypes,                                                  full_qualified_name, node, contnode)def _resolve_reference(env: BuildEnvironment, inv_name: Optional[str], inventory: Inventory,                       honor_disabled_refs: bool,                       node: pending_xref, contnode: TextElement) -> Optional[Element]:    # disabling should only be done if no inventory is given    honor_disabled_refs = honor_disabled_refs and inv_name is None    if honor_disabled_refs and '*' in env.config.intersphinx_disabled_reftypes:        return None    typ = node['reftype']    if typ == 'any':        for domain_name, domain in env.domains.items():            if honor_disabled_refs \                    and (domain_name + ":*") in env.config.intersphinx_disabled_reftypes:                continue            objtypes = list(domain.object_types)            res = _resolve_reference_in_domain(env, inv_name, inventory,                                               honor_disabled_refs,                                               domain, objtypes,                                               node, contnode)            if res is not None:                return res        return None    else:        domain_name = node.get('refdomain')        if not domain_name:             # only objects in domains are in the inventory             return None        objtypes = env.get_domain(domain).objtypes_for_role(node['reftype'])        if honor_disabled_refs \                and (domain_name + ":*") in env.config.intersphinx_disabled_reftypes:            return None        domain = env.get_domain(domain_name)        objtypes = domain.objtypes_for_role(typ)         if not objtypes:             return None        objtypes = ['%s:%s' % (domain, objtype) for objtype in objtypes]    if 'std:cmdoption' in objtypes:        # until Sphinx-1.6, cmdoptions are stored as std:option        objtypes.append('std:option')    if 'py:attribute' in objtypes:        # Since Sphinx-2.1, properties are stored as py:method        objtypes.append('py:method')    to_try = [(inventories.main_inventory, target)]    if domain:        full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)        if full_qualified_name:            to_try.append((inventories.main_inventory, full_qualified_name))    in_set = None    if ':' in target:        # first part may be the foreign doc set name        setname, newtarget = target.split(':', 1)        if setname in inventories.named_inventory:            in_set = setname            to_try.append((inventories.named_inventory[setname], newtarget))            if domain:                node['reftarget'] = newtarget                full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)                if full_qualified_name:                    to_try.append((inventories.named_inventory[setname], full_qualified_name))    for inventory, target in to_try:        for objtype in objtypes:            if objtype not in inventory:                # Continue if there's nothing of this kind in the inventory                continue            if target in inventory[objtype]:                # Case sensitive match, use it                proj, version, uri, dispname = inventory[objtype][target]            elif objtype == 'std:term':                # Check for potential case insensitive matches for terms only                target_lower = target.lower()                insensitive_matches = list(filter(lambda k: k.lower() == target_lower,                                                  inventory[objtype].keys()))                if insensitive_matches:                    proj, version, uri, dispname = inventory[objtype][insensitive_matches[0]]                else:                    # No case insensitive match either, continue to the next candidate                    continue            else:                # Could reach here if we're not a term but have a case insensitive match.                # This is a fix for terms specifically, but potentially should apply to                # other types.                continue        return _resolve_reference_in_domain(env, inv_name, inventory,                                            honor_disabled_refs,                                            domain, objtypes,                                            node, contnode)             if '://' not in uri and node.get('refdoc'):                # get correct path in case of subdirectories                uri = path.join(relative_path(node['refdoc'], '.'), uri)            if version:                reftitle = _('(in %s v%s)') % (proj, version)            else:                reftitle = _('(in %s)') % (proj,)            newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle)            if node.get('refexplicit'):                # use whatever title was given                newnode.append(contnode)            elif dispname == '-' or \                    (domain == 'std' and node['reftype'] == 'keyword'):                # use whatever title was given, but strip prefix                title = contnode.astext()                if in_set and title.startswith(in_set + ':'):                    newnode.append(contnode.__class__(title[len(in_set) + 1:],                                                      title[len(in_set) + 1:]))                else:                    newnode.append(contnode)            else:                # else use the given display name (used for :ref:)                newnode.append(contnode.__class__(dispname, dispname))            return newnode    # at least get rid of the ':' in the target if no explicit title given    if in_set is not None and not node.get('refexplicit', True):        if len(contnode) and isinstance(contnode[0], nodes.Text):            contnode[0] = nodes.Text(newtarget, contnode[0].rawsource)     return Nonedef inventory_exists(env: BuildEnvironment, inv_name: str) -> bool:    return inv_name in InventoryAdapter(env).named_inventorydef resolve_reference_in_inventory(env: BuildEnvironment,                                   inv_name: str,                                   node: pending_xref, contnode: TextElement                                   ) -> Optional[Element]:    """Attempt to resolve a missing reference via intersphinx references.    Resolution is tried in the given inventory with the target as is.    Requires ``inventory_exists(env, inv_name)``.    """    assert inventory_exists(env, inv_name)    return _resolve_reference(env, inv_name, InventoryAdapter(env).named_inventory[inv_name],                              False, node, contnode)def resolve_reference_any_inventory(env: BuildEnvironment,                                    honor_disabled_refs: bool,                                    node: pending_xref, contnode: TextElement                                    ) -> Optional[Element]:    """Attempt to resolve a missing reference via intersphinx references.    Resolution is tried with the target as is in any inventory.    """    return _resolve_reference(env, None, InventoryAdapter(env).main_inventory,                              honor_disabled_refs,                              node, contnode)def resolve_reference_detect_inventory(env: BuildEnvironment,                                       node: pending_xref, contnode: TextElement                                       ) -> Optional[Element]:    """Attempt to resolve a missing reference via intersphinx references.    Resolution is tried first with the target as is in any inventory.    If this does not succeed, then the target is split by the first ``:``,    to form ``inv_name:newtarget``. If ``inv_name`` is a named inventory, then resolution    is tried in that inventory with the new target.    """    # ordinary direct lookup, use data as is    res = resolve_reference_any_inventory(env, True, node, contnode)    if res is not None:        return res    # try splitting the target into 'inv_name:target'    target = node['reftarget']    if ':' not in target:        return None    inv_name, newtarget = target.split(':', 1)    if not inventory_exists(env, inv_name):        return None    node['reftarget'] = newtarget    res_inv = resolve_reference_in_inventory(env, inv_name, node, contnode)    node['reftarget'] = target    return res_invdef missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,                      contnode: TextElement) -> Optional[Element]:    """Attempt to resolve a missing reference via intersphinx references."""    return resolve_reference_detect_inventory(env, node, contnode)   def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None:


Question: Add an option to not use intersphinx references as a fallback That intersphinx references are used as fallbacks if a reference is not available in a project recently caused us a problem. We have a site () which is the latest build of . We use intersphinx as follows, so we can link to the latest documentation in some sections: Our docs included a label () so this reference was available on . This label was removed on a branch, along with one of the two references to this label. In this case we would expect that building the branch would fail, as there is a reference to a label which doesn't exist. Unexpectedly, the branch built successfully, because the label was found in as a fall back when it was not found locally. The branch was merged, and then later, when changed (because was built again) builds stopped working because there was a reference to a non-existent label. It would be good to have an option to not fall back, maybe something like .

app.add_config_value('intersphinx_mapping', {}, True)     app.add_config_value('intersphinx_cache_limit', 5, False)     app.add_config_value('intersphinx_timeout', None, False)    app.add_config_value('intersphinx_disabled_reftypes', [], True)     app.connect('config-inited', normalize_intersphinx_mapping, priority=800)     app.connect('builder-inited', load_mappings)     app.connect('missing-reference', missing_reference)diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py-- a/sphinx/util/typing.py++ b/sphinx/util/typing.py


Question: Add an option to not use intersphinx references as a fallback That intersphinx references are used as fallbacks if a reference is not available in a project recently caused us a problem. We have a site () which is the latest build of . We use intersphinx as follows, so we can link to the latest documentation in some sections: Our docs included a label () so this reference was available on . This label was removed on a branch, along with one of the two references to this label. In this case we would expect that building the branch would fail, as there is a reference to a label which doesn't exist. Unexpectedly, the branch built successfully, because the label was found in as a fall back when it was not found locally. The branch was merged, and then later, when changed (because was built again) builds stopped working because there was a reference to a non-existent label. It would be good to have an option to not fall back, maybe something like .

TitleGetter = Callable[[nodes.Node], str]  # inventory data on memoryInventory = Dict[str, Dict[str, Tuple[str, str, str, str]]]InventoryItem = Tuple[str, str, str, str]Inventory = Dict[str, Dict[str, InventoryItem]]   def get_type_hints(obj: Any, globalns: Dict = None, localns: Dict = None) -> Dict[str, Any]:


Question: Methods decorated with and do not get documented. EDIT: The problem seems to be that returns , thus sphinx can just lookup . However, returns the type of the returned object, since essentially, a ends up behaving like a class attribute. So Sphinx doesn't really have a chance to extract the docstring. EDIT 2: Seems like this will get fixed in python 3.10, cf. I will try to test this with the beta release. That is, since python version 3.9 we can write code like However, sphinx does not seem to document any such methods (regular decorated methods get documented just fine.) The following methods were erroneously not documented: - - - Methods that are decorated with both and should be documented appropriately. No response Ubuntu 20.04.2 LTS 6 3 , No response No response

option_spec = PyObject.option_spec.copy()     option_spec.update({         'abstractmethod': directives.flag,<ins>        'classmethod': directives.flag,</ins>         'type': directives.unchanged,     })


Question: Methods decorated with and do not get documented. EDIT: The problem seems to be that returns , thus sphinx can just lookup . However, returns the type of the returned object, since essentially, a ends up behaving like a class attribute. So Sphinx doesn't really have a chance to extract the docstring. EDIT 2: Seems like this will get fixed in python 3.10, cf. I will try to test this with the beta release. That is, since python version 3.9 we can write code like However, sphinx does not seem to document any such methods (regular decorated methods get documented just fine.) The following methods were erroneously not documented: - - - Methods that are decorated with both and should be documented appropriately. No response Ubuntu 20.04.2 LTS 6 3 , No response No response

return fullname, prefix      def get_signature_prefix(self, sig: str) -> str:        prefix = ['property']        prefix = []         if 'abstractmethod' in self.options:            prefix.insert(0, 'abstract')            prefix.append('abstract')        if 'classmethod' in self.options:            prefix.append('class')         prefix.append('property')         return ' '.join(prefix) + ' '      def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py-- a/sphinx/ext/autodoc/__init__.py++ b/sphinx/ext/autodoc/__init__.py


Question: Methods decorated with and do not get documented. EDIT: The problem seems to be that returns , thus sphinx can just lookup . However, returns the type of the returned object, since essentially, a ends up behaving like a class attribute. So Sphinx doesn't really have a chance to extract the docstring. EDIT 2: Seems like this will get fixed in python 3.10, cf. I will try to test this with the beta release. That is, since python version 3.9 we can write code like However, sphinx does not seem to document any such methods (regular decorated methods get documented just fine.) The following methods were erroneously not documented: - - - Methods that are decorated with both and should be documented appropriately. No response Ubuntu 20.04.2 LTS 6 3 , No response No response

isattr = False              doc = getdoc(member, self.get_attr, self.config.autodoc_inherit_docstrings,                         self.parent, self.object_name)                         self.object, membername)             if not isinstance(doc, str):                 # Ignore non-string __doc__                 doc = None


Question: Methods decorated with and do not get documented. EDIT: The problem seems to be that returns , thus sphinx can just lookup . However, returns the type of the returned object, since essentially, a ends up behaving like a class attribute. So Sphinx doesn't really have a chance to extract the docstring. EDIT 2: Seems like this will get fixed in python 3.10, cf. I will try to test this with the beta release. That is, since python version 3.9 we can write code like However, sphinx does not seem to document any such methods (regular decorated methods get documented just fine.) The following methods were erroneously not documented: - - - Methods that are decorated with both and should be documented appropriately. No response Ubuntu 20.04.2 LTS 6 3 , No response No response

@classmethod     def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any                             ) -> bool:        return inspect.isproperty(member) and isinstance(parent, ClassDocumenter)        if isinstance(parent, ClassDocumenter):            if inspect.isproperty(member):                return True            else:                __dict__ = safe_getattr(parent.object, '__dict__', {})                obj = __dict__.get(membername)                return isinstance(obj, classmethod) and inspect.isproperty(obj.__func__)        else:            return False    def import_object(self, raiseerror: bool = False) -> bool:        """Check the exisitence of uninitialized instance attribute when failed to import        the attribute."""        ret = super().import_object(raiseerror)        if ret and not inspect.isproperty(self.object):            __dict__ = safe_getattr(self.parent, '__dict__', {})            obj = __dict__.get(self.objpath[-1])            if isinstance(obj, classmethod) and inspect.isproperty(obj.__func__):                self.object = obj.__func__                self.isclassmethod = True                return True            else:                return False        self.isclassmethod = False        return ret      def document_members(self, all_members: bool = False) -> None:         pass


Question: Methods decorated with and do not get documented. EDIT: The problem seems to be that returns , thus sphinx can just lookup . However, returns the type of the returned object, since essentially, a ends up behaving like a class attribute. So Sphinx doesn't really have a chance to extract the docstring. EDIT 2: Seems like this will get fixed in python 3.10, cf. I will try to test this with the beta release. That is, since python version 3.9 we can write code like However, sphinx does not seem to document any such methods (regular decorated methods get documented just fine.) The following methods were erroneously not documented: - - - Methods that are decorated with both and should be documented appropriately. No response Ubuntu 20.04.2 LTS 6 3 , No response No response

sourcename = self.get_sourcename()         if inspect.isabstractmethod(self.object):             self.add_line('   :abstractmethod:', sourcename)        if self.isclassmethod:            self.add_line('   :classmethod:', sourcename)          if safe_getattr(self.object, 'fget', None) and self.config.autodoc_typehints != 'none':             try:diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py-- a/sphinx/util/inspect.py++ b/sphinx/util/inspect.py


Question: Methods decorated with and do not get documented. EDIT: The problem seems to be that returns , thus sphinx can just lookup . However, returns the type of the returned object, since essentially, a ends up behaving like a class attribute. So Sphinx doesn't really have a chance to extract the docstring. EDIT 2: Seems like this will get fixed in python 3.10, cf. I will try to test this with the beta release. That is, since python version 3.9 we can write code like However, sphinx does not seem to document any such methods (regular decorated methods get documented just fine.) The following methods were erroneously not documented: - - - Methods that are decorated with both and should be documented appropriately. No response Ubuntu 20.04.2 LTS 6 3 , No response No response

return isinstance(obj, (partial, partialmethod))  def isclassmethod(obj: Any) -> bool:def isclassmethod(obj: Any, cls: Any = None, name: str = None) -> bool:     """Check if the object is classmethod."""     if isinstance(obj, classmethod):         return True     elif inspect.ismethod(obj) and obj.__self__ is not None and isclass(obj.__self__):         return True    elif cls and name:        for basecls in getmro(cls):            meth = basecls.__dict__.get(name)            if meth:                return isclassmethod(meth)      return False


Question: Methods decorated with and do not get documented. EDIT: The problem seems to be that returns , thus sphinx can just lookup . However, returns the type of the returned object, since essentially, a ends up behaving like a class attribute. So Sphinx doesn't really have a chance to extract the docstring. EDIT 2: Seems like this will get fixed in python 3.10, cf. I will try to test this with the beta release. That is, since python version 3.9 we can write code like However, sphinx does not seem to document any such methods (regular decorated methods get documented just fine.) The following methods were erroneously not documented: - - - Methods that are decorated with both and should be documented appropriately. No response Ubuntu 20.04.2 LTS 6 3 , No response No response

* inherited docstring     * inherited decorated methods     """<ins>    if cls and name and isclassmethod(obj, cls, name):        for basecls in getmro(cls):            meth = basecls.__dict__.get(name)            if meth:                return getdoc(meth.__func__)</ins>     doc = attrgetter(obj, '__doc__', None)     if ispartial(obj) and doc == obj.__class__.__doc__:         return getdoc(obj.func)


Question: PEP 585 type hints not rendered correctly If you use a PEP 585 generic as an annotation i.e. , autodoc renders the annotation as rather than , this behaviour differs from using which renders as expected. Fixing this is quite simple as far as I can tell, just needs to check if the annotation has and if it does, return An annotation of to be rendered as ! Mac Python 3.9.3 1 autodoc No response No response

return INVALID_BUILTIN_CLASSES[annotation]     elif (getattr(annotation, '__module__', None) == 'builtins' and           hasattr(annotation, '__qualname__')):        return annotation.__qualname__        if hasattr(annotation, '__args__'):  # PEP 585 generic            return repr(annotation)        else:            return annotation.__qualname__     elif annotation is Ellipsis:         return '...'


Question: github linkcheck anchor change in 4.1.0 break some usage Given a link like: in a github doc, with release 4.1.0 this will fail with linkcheck, while previously it worked. It passes. No response Linux 5 0 No response No response The relevant change happened in Failing test logs:

app.add_event('linkcheck-process-uri')      app.connect('config-inited', compile_linkcheck_allowed_redirects, priority=800)    app.connect('linkcheck-process-uri', rewrite_github_anchor)    # FIXME: Disable URL rewrite handler for github.com temporarily.    # ref: https://github.com/sphinx-doc/sphinx/issues/9435    # app.connect('linkcheck-process-uri', rewrite_github_anchor)      return {         'version': 'builtin',


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

_string_re = re.compile(r"[LuU8]?('([^'\\]*(?:\\.[^'\\]*)*)'"                         r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S) <ins>_simple_type_sepcifiers_re = re.compile(r"""(?x)    \b(    void|_Bool|bool    # Integer    # -------    |((signed|unsigned)\s+)?(char|(        ((long\s+long|long|short)\s+)?int    ))    |__uint128|__int128    # extensions    |((signed|unsigned)\s+)?__int(8|16|32|64|128)    # Floating-point    # --------------    |(float|double|long\s+double)(\s+(_Complex|complex|_Imaginary|imaginary))?    |(_Complex|complex|_Imaginary|imaginary)\s+(float|double|long\s+double)    |_Decimal(32|64|128)    # extensions    |__float80|_Float64x|__float128|_Float128|__ibm128    |__fp16    # Fixed-point, extension    |(_Sat\s+)?((signed|unsigned)\s+)?((short|long|long\s+long)\s+)?(_Fract|fract|_Accum|accum)    # Integer types that could be prefixes of the previous ones    # ---------------------------------------------------------    |((signed|unsigned)\s+)?(long\s+long|long|short)    |signed|unsigned    )\b""")</ins>  class _DuplicateSymbolError(Exception):     def __init__(self, symbol: "Symbol", declaration: "ASTDeclaration") -> None:


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

class ASTTrailingTypeSpecFundamental(ASTTrailingTypeSpec):     def __init__(self, name: str) -> None:        self.name = name        self.names = name.split()      def _stringify(self, transform: StringifyTransform) -> str:        return self.name        return ' '.join(self.names)      def describe_signature(self, signode: TextElement, mode: str,                            env: "BuildEnvironment", symbol: "Symbol") -> None:        signode += addnodes.desc_sig_keyword_type(self.name, self.name)        first = True        for n in self.names:            if not first:                signode += addnodes.desc_sig_space()            else:                first = False            signode += addnodes.desc_sig_keyword_type(n, n)   class ASTTrailingTypeSpecName(ASTTrailingTypeSpec):


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

class DefinitionParser(BaseParser):<del>    # those without signedness and size modifiers    # see https://en.cppreference.com/w/cpp/language/types    _simple_fundamental_types = (        'void', '_Bool', 'bool', 'char', 'int', 'float', 'double',        '__int64',    )    _prefix_keys = ('struct', 'enum', 'union')</del>     @property     def language(self) -> str:         return 'C'


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

return ASTNestedName(names, rooted)      def _parse_trailing_type_spec(self) -> ASTTrailingTypeSpec:        # fundamental types        # fundamental types, https://en.cppreference.com/w/c/language/type        # and extensions         self.skip_ws()        for t in self._simple_fundamental_types:            if self.skip_word(t):                return ASTTrailingTypeSpecFundamental(t)        # TODO: this could/should be more strict        elements = []        if self.skip_word_and_ws('signed'):            elements.append('signed')        elif self.skip_word_and_ws('unsigned'):            elements.append('unsigned')        while 1:            if self.skip_word_and_ws('short'):                elements.append('short')            elif self.skip_word_and_ws('long'):                elements.append('long')            else:                break        if self.skip_word_and_ws('char'):            elements.append('char')        elif self.skip_word_and_ws('int'):            elements.append('int')        elif self.skip_word_and_ws('double'):            elements.append('double')        elif self.skip_word_and_ws('__int64'):            elements.append('__int64')        if len(elements) > 0:            return ASTTrailingTypeSpecFundamental(' '.join(elements))        if self.match(_simple_type_sepcifiers_re):            return ASTTrailingTypeSpecFundamental(self.matched_text)          # prefixed         prefix = None         self.skip_ws()        for k in self._prefix_keys:        for k in ('struct', 'enum', 'union'):             if self.skip_word_and_ws(k):                 prefix = k                 breakdiff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py-- a/sphinx/domains/cpp.py++ b/sphinx/domains/cpp.py


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

'while', 'xor', 'xor_eq' ] <ins>_simple_type_sepcifiers_re = re.compile(r"""(?x)    \b(    auto|void|bool    # Integer    # -------    |((signed|unsigned)\s+)?(char|__int128|(        ((long\s+long|long|short)\s+)?int    ))    |wchar_t|char(8|16|32)_t    # extensions    |((signed|unsigned)\s+)?__int(64|128)    # Floating-point    # --------------    |(float|double|long\s+double)(\s+(_Complex|_Imaginary))?    |(_Complex|_Imaginary)\s+(float|double|long\s+double)    # extensions    |__float80|_Float64x|__float128|_Float128    # Integer types that could be prefixes of the previous ones    # ---------------------------------------------------------    |((signed|unsigned)\s+)?(long\s+long|long|short)    |signed|unsigned    )\b""")</ins> _max_id = 4 _id_prefix = [None, '', '_CPPv2', '_CPPv3', '_CPPv4'] # Ids are used in lookup keys which are used across pickled files,


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

'long long int': 'x',     'signed long long': 'x',     'signed long long int': 'x',    '__int64': 'x',     'unsigned long long': 'y',     'unsigned long long int': 'y',    '__int128': 'n',    'signed __int128': 'n',    'unsigned __int128': 'o',     'float': 'f',     'double': 'd',     'long double': 'e',    '__float80': 'e', '_Float64x': 'e',    '__float128': 'g', '_Float128': 'g',    'float _Complex': 'Cf', '_Complex float': 'Cf',    'double _Complex': 'Cd', '_Complex double': 'Cd',    'long double _Complex': 'Ce', '_Complex long double': 'Ce',    'float _Imaginary': 'f', '_Imaginary float': 'f',    'double _Imaginary': 'd', '_Imaginary double': 'd',    'long double _Imaginary': 'e', '_Imaginary long double': 'e',     'auto': 'Da',     'decltype(auto)': 'Dc',     'std::nullptr_t': 'Dn'


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

class ASTTrailingTypeSpecFundamental(ASTTrailingTypeSpec):     def __init__(self, name: str) -> None:        self.name = name        self.names = name.split()      def _stringify(self, transform: StringifyTransform) -> str:        return self.name        return ' '.join(self.names)      def get_id(self, version: int) -> str:         if version == 1:             res = []            for a in self.name.split(' '):            for a in self.names:                 if a in _id_fundamental_v1:                     res.append(_id_fundamental_v1[a])                 else:                     res.append(a)             return '-'.join(res)         if self.name not in _id_fundamental_v2:        txt = str(self)        if txt not in _id_fundamental_v2:             raise Exception(                 'Semi-internal error: Fundamental type "%s" can not be mapped '                'to an id. Is it a true fundamental type? If not so, the '                'parser should have rejected it.' % self.name)        return _id_fundamental_v2[self.name]                'to an ID. Is it a true fundamental type? If not so, the '                'parser should have rejected it.' % txt)        return _id_fundamental_v2[txt]      def describe_signature(self, signode: TextElement, mode: str,                            env: "BuildEnvironment", symbol: "Symbol") -> None:        signode += addnodes.desc_sig_keyword_type(self.name, self.name)        first = True        for n in self.names:            if not first:                signode += addnodes.desc_sig_space()            else:                first = False            signode += addnodes.desc_sig_keyword_type(n, n)   class ASTTrailingTypeSpecDecltypeAuto(ASTTrailingTypeSpec):


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

class DefinitionParser(BaseParser):<del>    # those without signedness and size modifiers    # see https://en.cppreference.com/w/cpp/language/types    _simple_fundemental_types = (        'void', 'bool', 'char', 'wchar_t', 'char8_t', 'char16_t', 'char32_t',        'int', 'float', 'double', 'auto'    )    _prefix_keys = ('class', 'struct', 'enum', 'union', 'typename')</del>     @property     def language(self) -> str:         return 'C++'


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

# ==========================================================================      def _parse_trailing_type_spec(self) -> ASTTrailingTypeSpec:        # fundemental types        # fundamental types, https://en.cppreference.com/w/cpp/language/type        # and extensions         self.skip_ws()        for t in self._simple_fundemental_types:            if self.skip_word(t):                return ASTTrailingTypeSpecFundamental(t)        # TODO: this could/should be more strict        elements = []        if self.skip_word_and_ws('signed'):            elements.append('signed')        elif self.skip_word_and_ws('unsigned'):            elements.append('unsigned')        while 1:            if self.skip_word_and_ws('short'):                elements.append('short')            elif self.skip_word_and_ws('long'):                elements.append('long')            else:                break        if self.skip_word_and_ws('char'):            elements.append('char')        elif self.skip_word_and_ws('int'):            elements.append('int')        elif self.skip_word_and_ws('double'):            elements.append('double')        if len(elements) > 0:            return ASTTrailingTypeSpecFundamental(' '.join(elements))        if self.match(_simple_type_sepcifiers_re):            return ASTTrailingTypeSpecFundamental(self.matched_text)          # decltype         self.skip_ws()


Question: Missing support for GNU extension types like or I'm currently working on the transition of the GNU C compiler (GCC) manuals and I noticed there are unsupported C extensions like: where I see the following parsing error: Right now, there's some special casing for e.g. 'unsigned' type: One possible fix is adding the mentioned C extension handling for the following types: or I can see a domain parser can become public via an API entry point: What do you think?

# prefixed         prefix = None         self.skip_ws()        for k in self._prefix_keys:        for k in ('class', 'struct', 'enum', 'union', 'typename'):             if self.skip_word_and_ws(k):                 prefix = k                 break


Question: Cross-references don't work in property's type annotations A documented type in property's type annotation does not get cross-referenced: I expected the documented type in property's type annotation to be cross-referenced. Here's a link to the generated docs: https://sphinx-issue- Windows 10, Ubuntu 18.04 7, 3.8, 3.9 2 No response No response

typ = self.options.get('type')         if typ:            signode += addnodes.desc_annotation(typ, ': ' + typ)            annotations = _parse_annotation(typ, self.env)            signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)          return fullname, prefix


Question: Nitpick flags Literal annotation values as missing py:class When a value is present in a type annotation as , sphinx will treat the value as a . With nitpick enabled, values like end up failing, because is not a class. This is a problem for builds which want to use to catch doc errors. Setup a simple function which uses Literal, then attempt to autodoc it. e.g. I've pushed an example to . Just run with available to see the failing build. (or whatever literal value) should be present in the type annotation but should not trigger the nitpick warning. No response Linux 8, 3.9 2 autodoc No response No response

if node.value is Ellipsis:                 return [addnodes.desc_sig_punctuation('', "...")]             else:                return [nodes.Text(node.value)]                return [nodes.Text(repr(node.value))]         elif isinstance(node, ast.Expr):             return unparse(node.value)         elif isinstance(node, ast.Index):


Question: Nitpick flags Literal annotation values as missing py:class When a value is present in a type annotation as , sphinx will treat the value as a . With nitpick enabled, values like end up failing, because is not a class. This is a problem for builds which want to use to catch doc errors. Setup a simple function which uses Literal, then attempt to autodoc it. e.g. I've pushed an example to . Just run with available to see the failing build. (or whatever literal value) should be present in the type annotation but should not trigger the nitpick warning. No response Linux 8, 3.9 2 autodoc No response No response

result.append(addnodes.desc_sig_punctuation('', '['))             result.extend(unparse(node.slice))             result.append(addnodes.desc_sig_punctuation('', ']'))<ins>            # Wrap the Text nodes inside brackets by literal node if the subscript is a Literal            if result[0] in ('Literal', 'typing.Literal'):                for i, subnode in enumerate(result[1:], start=1):                    if isinstance(subnode, nodes.Text):                        result[i] = nodes.literal('', '', subnode)</ins>             return result         elif isinstance(node, ast.Tuple):             if node.elts:


Question: Nitpick flags Literal annotation values as missing py:class When a value is present in a type annotation as , sphinx will treat the value as a . With nitpick enabled, values like end up failing, because is not a class. This is a problem for builds which want to use to catch doc errors. Setup a simple function which uses Literal, then attempt to autodoc it. e.g. I've pushed an example to . Just run with available to see the failing build. (or whatever literal value) should be present in the type annotation but should not trigger the nitpick warning. No response Linux 8, 3.9 2 autodoc No response No response

tree = ast_parse(annotation)         result = unparse(tree)         for i, node in enumerate(result):            if isinstance(node, nodes.Text) and node.strip():            if isinstance(node, nodes.literal):                result[i] = node[0]            elif isinstance(node, nodes.Text) and node.strip():                 result[i] = type_to_xref(str(node), env)         return result     except SyntaxError:


Question: Incorrect base class detection I have a chain of subclasses, like A -B -C -D. When I document class D, it lists the base class as A instead of C. I would expect the base class to be the direct super class. No response macOS 10.15.7, Linux (whatever RtD uses) 11 1, 4.0.2 No response I don't think this is the same as because I can reproduce it with 4.0.1 too. Could be related to . For a class like , even though the super class is , the base class is listed as .

# add inheritance info, if wanted         if not self.doc_as_attr and self.options.show_inheritance:            if hasattr(self.object, '__orig_bases__') and len(self.object.__orig_bases__):            if inspect.getorigbases(self.object):                 # A subclass of generic types                 # refs: PEP-560 <https://www.python.org/dev/peps/pep-0560/>                 bases = list(self.object.__orig_bases__)diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py-- a/sphinx/util/inspect.py++ b/sphinx/util/inspect.py


Question: Incorrect base class detection I have a chain of subclasses, like A -B -C -D. When I document class D, it lists the base class as A instead of C. I would expect the base class to be the direct super class. No response macOS 10.15.7, Linux (whatever RtD uses) 11 1, 4.0.2 No response I don't think this is the same as because I can reproduce it with 4.0.1 too. Could be related to . For a class like , even though the super class is , the base class is listed as .

return tuple()  <ins>def getorigbases(obj: Any) -> Optional[Tuple[Any, ...]]:    """Get __orig_bases__ from *obj* safely."""    if not inspect.isclass(obj):        return None    # Get __orig_bases__ from obj.__dict__ to avoid accessing the parent's __orig_bases__.    # refs: https://github.com/sphinx-doc/sphinx/issues/9607    __dict__ = safe_getattr(obj, '__dict__', {})    __orig_bases__ = __dict__.get('__orig_bases__')    if isinstance(__orig_bases__, tuple) and len(__orig_bases__) > 0:        return __orig_bases__    else:        return None</ins> def getslots(obj: Any) -> Optional[Dict]:     """Get __slots__ attribute of the class as dict.


Question: Inherited classes not correctly documented when mocked We're experiencing an issue when documenting classes that inherit mocked classes. However, classes which inherit other classes from our own package are ok. This issue appears to be dependent on the version: : Everything is OK. : Classes that inherit mocked classes are not documented. (see ). This is fixed in . : The previously missing classes are now documented, but there is a problem with the "Bases" section in the docs. Example: In the docs for in this readthedocs build https://seldon--, the base class is listed as "Bases: " instead of "Bases: ". The "Bases" section should report not . i.e. see https://seldon-- ! ! Ubuntu 18.04 (used by readthedocs/build:6.0) 11 ["", "", "", "", "", "", "", "", "", "sphinxautodoctypehints", "", "nbsphinx", "nbsphinxlink", "mystparser"] No response demo PR: readthedocs demo build: https://seldon--

"""Used by autodoc_mock_imports."""      __display_name__ = '_MockObject'<ins>    __name__ = ''</ins>     __sphinx_mock__ = True     __sphinx_decorator_args__: Tuple[Any, ...] = ()


Question: Inherited classes not correctly documented when mocked We're experiencing an issue when documenting classes that inherit mocked classes. However, classes which inherit other classes from our own package are ok. This issue appears to be dependent on the version: : Everything is OK. : Classes that inherit mocked classes are not documented. (see ). This is fixed in . : The previously missing classes are now documented, but there is a problem with the "Bases" section in the docs. Example: In the docs for in this readthedocs build https://seldon--, the base class is listed as "Bases: " instead of "Bases: ". The "Bases" section should report not . i.e. see https://seldon-- ! ! Ubuntu 18.04 (used by readthedocs/build:6.0) 11 ["", "", "", "", "", "", "", "", "", "sphinxautodoctypehints", "", "nbsphinx", "nbsphinxlink", "mystparser"] No response demo PR: readthedocs demo build: https://seldon--

return super().__new__(cls)      def __init__(self, *args: Any, **kwargs: Any) -> None:        self.__qualname__ = ''        self.__qualname__ = self.__name__      def __len__(self) -> int:         return 0


Question: Inherited classes not correctly documented when mocked We're experiencing an issue when documenting classes that inherit mocked classes. However, classes which inherit other classes from our own package are ok. This issue appears to be dependent on the version: : Everything is OK. : Classes that inherit mocked classes are not documented. (see ). This is fixed in . : The previously missing classes are now documented, but there is a problem with the "Bases" section in the docs. Example: In the docs for in this readthedocs build https://seldon--, the base class is listed as "Bases: " instead of "Bases: ". The "Bases" section should report not . i.e. see https://seldon-- ! ! Ubuntu 18.04 (used by readthedocs/build:6.0) 11 ["", "", "", "", "", "", "", "", "", "sphinxautodoctypehints", "", "nbsphinx", "nbsphinxlink", "mystparser"] No response demo PR: readthedocs demo build: https://seldon--

attributes: Any = None, decorator_args: Tuple = ()) -> Any:     attrs = {'__module__': module,              '__display_name__': module + '.' + name,<ins>             '__name__': name,</ins>              '__sphinx_decorator_args__': decorator_args}     attrs.update(attributes or {})


Question: python bases in packages - follow up on Is your feature request related to a problem? Please describe. Same problem as described in Describe the solution you'd like sphinx checks if the base class is documented somewhere. If yes, it inserts the reference to the corresponding page automatically. Describe alternatives you've considered As originally proposed in , allow to return a list of strings that will be appended to Additional context was marked as but that PR unfortunately doesn't solve the problem: While I now can return a different base class, I still can't control the text of the hyperlink for that class. With being allowed to return strings, one could just return something like telegram.TelegramObject` PS: maybe we can just reopen and continue discussion there …

return ':py:obj:`None`'         elif cls is Ellipsis:             return '...'<ins>        elif isinstance(cls, str):            return cls</ins>         elif cls in INVALID_BUILTIN_CLASSES:             return ':py:class:`%s`' % INVALID_BUILTIN_CLASSES[cls]         elif inspect.isNewType(cls):


Question: autodoctypehintsdescriptiontarget not working with Napoleon I was trying to use the config option combined with the Napoleon plugin (using Google style). The return types were missing from the resulting documentation. Just generate the documentation using Napoleon and the config options: Generate the documentation of a function with the following docstring: As the return is specified, the return type should be present in the documentation, either as a rtype section or as part of the return description. ! Win 8 0 '', '', '', '', '', No response No response

elif parts[0] == 'type':             name = ' '.join(parts[1:])             has_type.add(name)        elif parts[0] == 'return':        elif parts[0] in ('return', 'returns'):             has_description.add('return')         elif parts[0] == 'rtype':             has_type.add('return')      # Add 'type' for parameters with a description but no declared type.     for name in annotations:        if name == 'return':        if name in ('return', 'returns'):             continue         if name in has_description and name not in has_type:             field = nodes.field()


Question: An index entry with parens was registered for directive with option An index entry with parens was registered for directive with option. It should not have parens. An index entry for the property should not have parens. N/A <img width="528" alt=" 2021-10-03 13 00 53" src="https://user-"Mac 6 HEAD of 4.x No response No response No response

if 'classmethod' in self.options:             return _('%s() (%s class method)') % (methname, clsname)         elif 'property' in self.options:            return _('%s() (%s property)') % (methname, clsname)            return _('%s (%s property)') % (methname, clsname)         elif 'staticmethod' in self.options:             return _('%s() (%s static method)') % (methname, clsname)         else:


Question: needsextensions checks versions using strings The check is handy for verifying minimum extension versions, but it only checks versions in a 'string-like' manner. This means any version 9 is not allowed for any check of something 1. That is, treated as string '0.6' '0.10', but treated as versions '0.6' < '0.10'. Since Sphinx does the former, some extension versions may not be allowed when they should be. This passes just fine, because the requirements pin sphinx-gallery to 0.9. But if you then update to the current 0.10 release: results in a failure due to a "not new enough" version: sphinx-gallery 0.10.0 should be accepted if 0.6 is the minimum specified. No response Fedora 6 2 No response No response No response

from typing import TYPE_CHECKING, Any, Dict <ins>from packaging.version import InvalidVersion, Version</ins> from sphinx.config import Config from sphinx.errors import VersionRequirementError from sphinx.locale import __


Question: needsextensions checks versions using strings The check is handy for verifying minimum extension versions, but it only checks versions in a 'string-like' manner. This means any version 9 is not allowed for any check of something 1. That is, treated as string '0.6' '0.10', but treated as versions '0.6' < '0.10'. Since Sphinx does the former, some extension versions may not be allowed when they should be. This passes just fine, because the requirements pin sphinx-gallery to 0.9. But if you then update to the current 0.10 release: results in a failure due to a "not new enough" version: sphinx-gallery 0.10.0 should be accepted if 0.6 is the minimum specified. No response Fedora 6 2 No response No response No response

'but it is not loaded.'), extname)             continue         if extension.version == 'unknown version' or reqversion > extension.version:        fulfilled = True        if extension.version == 'unknown version':            fulfilled = False        else:            try:                if Version(reqversion) > Version(extension.version):                    fulfilled = False            except InvalidVersion:                if reqversion > extension.version:                    fulfilled = False        if not fulfilled:             raise VersionRequirementError(__('This project needs the extension %s at least in '                                              'version %s and therefore cannot be built with '                                              'the loaded version (%s).') %


Question: Overridden classmethod documentation not inherited with autodoc The documentation for a classmethod in a parent class is not inherited by the method re-defined (without documentation) in a child class Module : Sphinx configuration : Documentation index : Build: Overridden classmethod to inherit documentation from parent class ! Ubuntu 20.04 8 0 returns the expected value

for basecls in getmro(cls):             meth = basecls.__dict__.get(name)             if meth and hasattr(meth, '__func__'):                return getdoc(meth.__func__)                doc = getdoc(meth.__func__)                if doc is not None or not allow_inherited:                    return doc      doc = attrgetter(obj, '__doc__', None)     if ispartial(obj) and doc == obj.__class__.__doc__:


Question: Nitpick flags Literal annotation values as missing py:class (with type hints in description) This is basically the same issue as , which was fixed in . However, I still get this issue when using . Comment out the line in and it is successful, as shown below (and removing the build artifacts to start fresh). No error, the build should succeed. See attachment in "How to Reproduce" section N/A - output is shown in "How to Reproduce" section Linux and Windows 9 0 , N/A This re-produces for me on both Linux and Windows. I think the source of it issue is probably from in since this function would otherwise be skipped if the type hints are left in the signature. But I haven't yet been able to track it all the way down to the error.

split_contnode = bool(contnode and contnode.astext() == target)         in_literal = False         results = []         for sub_target in filter(None, sub_targets):             if split_contnode:                 contnode = nodes.Text(sub_target)             if delims_re.match(sub_target):            if in_literal or delims_re.match(sub_target):                 results.append(contnode or innernode(sub_target, sub_target))             else:                 results.append(self.make_xref(rolename, domain, sub_target,                                               innernode, contnode, env, inliner, location))             if sub_target in ('Literal', 'typing.Literal'):                in_literal = True         return results


Question: Re-opening : hexadecimal default arguments are changed to decimal I am experiencing the exact same problem as described in : hexadecimal default arguments are changed to decimal. Autodoc the following function: HTML result looks like this Hexadecimal defaults should not be converted to decimal, or at least there should be an option to enforce this behaviour. I'm afraid this is private No response Linux Ubuntu 20.04 10 0 autodoc, intersphinx, napoleon Chromium 94 No response

import ast import inspectfrom typing import Any, Dictimport sysfrom typing import Any, Dict, List, Optional  from sphinx.application import Sphinx from sphinx.locale import __


Question: Re-opening : hexadecimal default arguments are changed to decimal I am experiencing the exact same problem as described in : hexadecimal default arguments are changed to decimal. Autodoc the following function: HTML result looks like this Hexadecimal defaults should not be converted to decimal, or at least there should be an option to enforce this behaviour. I'm afraid this is private No response Linux Ubuntu 20.04 10 0 autodoc, intersphinx, napoleon Chromium 94 No response

return None  def get_default_value(lines: List[str], position: ast.AST) -> Optional[str]:    try:        if sys.version_info < (3, 8):  # only for py38+            return None        elif position.lineno == position.end_lineno:            line = lines[position.lineno - 1]            return line[position.col_offset:position.end_col_offset]        else:            # multiline value is not supported now            return None    except (AttributeError, IndexError):        return None def 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:        lines = inspect.getsource(obj).splitlines()        if lines[0].startswith((' ', r'\t')):            lines.insert(0, '')  # insert a dummy line to follow what get_function_def() does.    except OSError:        lines = []     try:         function = get_function_def(obj)         if function.args.defaults or function.args.kw_defaults: