Question: autodoc: Load automatically After typehints enough matured, it should be loaded automatically from autodoc extension. refs:

def merge_typehints(app: Sphinx, domain: str, objtype: str, contentnode: Element) -> None:     if domain != 'py':         return    if app._autodoc_typehints_description is False:  # type: ignore    if app.config.autodoc_typehints != 'description':         return      signature = cast(addnodes.desc_signature, contentnode.parent[0])


Question: autodoc: Load automatically After typehints enough matured, it should be loaded automatically from autodoc extension. refs:

def setup(app: Sphinx) -> Dict[str, Any]:<del>    app.setup_extension('sphinx.ext.autodoc')    app.config.values['autodoc_typehints'] = ('signature', True,                                              ENUM("signature", "description", "none"))    app.connect('config-inited', config_inited)</del>     app.connect('autodoc-process-signature', record_typehints)     app.connect('object-description-transform', merge_typehints)


Question: "Could not parse arglist" with operator pow Describe the bug With the rst I get the errors Expected behavior A clear and concise description of what you expected to happen. Environment info OS: Ubuntu 18.04 Python version: 3.6.9 Sphinx version: branches 3.x and master, but not 2.x Sphinx extensions: none Extra tools: none

"""  import sysfrom typing import Listfrom typing import Dict, List, Type  if sys.version_info > (3, 8):     import ast


Question: "Could not parse arglist" with operator pow Describe the bug With the rst I get the errors Expected behavior A clear and concise description of what you expected to happen. Environment info OS: Ubuntu 18.04 Python version: 3.6.9 Sphinx version: branches 3.x and master, but not 2.x Sphinx extensions: none Extra tools: none

import ast  # type: ignore  <ins>OPERATORS = {    ast.Add: "+",    ast.And: "and",    ast.BitAnd: "&",    ast.BitOr: "|",    ast.BitXor: "^",    ast.Div: "/",    ast.FloorDiv: "//",    ast.Invert: "~",    ast.LShift: "<<",    ast.MatMult: "@",    ast.Mult: "*",    ast.Mod: "%",    ast.Not: "not",    ast.Pow: "**",    ast.Or: "or",    ast.RShift: ">>",    ast.Sub: "-",    ast.UAdd: "+",    ast.USub: "-",}  # type: Dict[Type[ast.AST], str]</ins> def parse(code: str, mode: str = 'exec') -> "ast.AST":     """Parse the *code* using built-in ast or typed_ast.


Question: "Could not parse arglist" with operator pow Describe the bug With the rst I get the errors Expected behavior A clear and concise description of what you expected to happen. Environment info OS: Ubuntu 18.04 Python version: 3.6.9 Sphinx version: branches 3.x and master, but not 2.x Sphinx extensions: none Extra tools: none

return None     elif isinstance(node, str):         return node<ins>    elif node.__class__ in OPERATORS:        return OPERATORS[node.__class__]</ins>     elif isinstance(node, ast.arg):         if node.annotation:             return "%s: %s" % (node.arg, unparse(node.annotation))


Question: "Could not parse arglist" with operator pow Describe the bug With the rst I get the errors Expected behavior A clear and concise description of what you expected to happen. Environment info OS: Ubuntu 18.04 Python version: 3.6.9 Sphinx version: branches 3.x and master, but not 2.x Sphinx extensions: none Extra tools: none

return unparse_arguments(node)     elif isinstance(node, ast.Attribute):         return "%s.%s" % (unparse(node.value), node.attr)<ins>    elif isinstance(node, ast.BinOp):        return " ".join(unparse(e) for e in [node.left, node.op, node.right])    elif isinstance(node, ast.BoolOp):        op = " %s " % unparse(node.op)        return op.join(unparse(e) for e in node.values)</ins>     elif isinstance(node, ast.Bytes):         return repr(node.s)     elif isinstance(node, ast.Call):


Question: "Could not parse arglist" with operator pow Describe the bug With the rst I get the errors Expected behavior A clear and concise description of what you expected to happen. Environment info OS: Ubuntu 18.04 Python version: 3.6.9 Sphinx version: branches 3.x and master, but not 2.x Sphinx extensions: none Extra tools: none

return repr(node.s)     elif isinstance(node, ast.Subscript):         return "%s[%s]" % (unparse(node.value), unparse(node.slice))<ins>    elif isinstance(node, ast.UnaryOp):        return "%s %s" % (unparse(node.op), unparse(node.operand))</ins>     elif isinstance(node, ast.Tuple):         return ", ".join(unparse(e) for e in node.elts)     elif sys.version_info > (3, 6) and isinstance(node, ast.Constant):


Question: Napoleon's Attributes directive ignores :noindex: option. Description of the bug Sphinxcontrib-napoleon's directive appears to ignore the option. The following reST code produces an index that includes the directives found in but leaves out all other directives: Expected behavior The above example should produce an empty document index. Environment info I am using the Sphinx packages that are provided by Ubuntu 18.04 and installed Napoleon with pip3 afterwards: The file is from https://sphinxcontrib- I used to configure my directory, edited to include and set the Python path, then typed .

if _type:                     lines.append(':vartype %s: %s' % (_name, _type))             else:                lines.extend(['.. attribute:: ' + _name, ''])                lines.append('.. attribute:: ' + _name)                if self._opt and 'noindex' in self._opt:                    lines.append('   :noindex:')                lines.append('')                 fields = self._format_field('', '', _desc)                 lines.extend(self._indent(fields, 3))                 if _type:


Question: Napoleon's Attributes directive ignores :noindex: option. Description of the bug Sphinxcontrib-napoleon's directive appears to ignore the option. The following reST code produces an index that includes the directives found in but leaves out all other directives: Expected behavior The above example should produce an empty document index. Environment info I am using the Sphinx packages that are provided by Ubuntu 18.04 and installed Napoleon with pip3 afterwards: The file is from https://sphinxcontrib- I used to configure my directory, edited to include and set the Python path, then typed .

lines = []  # type: List[str]         for _name, _type, _desc in self._consume_fields(parse_type=False):             lines.append('.. method:: %s' % _name)<ins>            if self._opt and 'noindex' in self._opt:                lines.append('   :noindex:')</ins>             if _desc:                 lines.extend([''] + self._indent(_desc, 3))             lines.append('')


Question: Files with same name but different extensions leads to unexpected behaviour Describe the bug If there are multiple files with the same name but different file extensions; sphinx will silently choose only one to parse: To Reproduce Steps to reproduce the behavior: Given I have an extension installed to parse with: This will actually include in the document, not Expected behavior A clear and concise description of what you expected to happen. Ideally you would have a config option to specify the order of preference for file extensions, or if not set, a warning would be logged. Your project Link to your sphinx project, or attach zipped small project sample. First noted in: Screenshots If applicable, add screenshots to help explain your problem. Environment info OS: Mac Python version: 3.7.6 Sphinx version: 2.4.4 Sphinx extensions: Additional context Add any other context about the problem here. [e.g. URL or Ticket]

"""  import os<ins>from glob import glob</ins>  from sphinx.locale import __ from sphinx.util import get_matching_files


Question: Files with same name but different extensions leads to unexpected behaviour Describe the bug If there are multiple files with the same name but different file extensions; sphinx will silently choose only one to parse: To Reproduce Steps to reproduce the behavior: Given I have an extension installed to parse with: This will actually include in the document, not Expected behavior A clear and concise description of what you expected to happen. Ideally you would have a config option to specify the order of preference for file extensions, or if not set, a warning would be logged. Your project Link to your sphinx project, or attach zipped small project sample. First noted in: Screenshots If applicable, add screenshots to help explain your problem. Environment info OS: Mac Python version: 3.7.6 Sphinx version: 2.4.4 Sphinx extensions: Additional context Add any other context about the problem here. [e.g. URL or Ticket]

for filename in get_matching_files(self.srcdir, excludes):  # type: ignore             docname = self.path2doc(filename)             if docname:                if os.access(os.path.join(self.srcdir, filename), os.R_OK):                if docname in self.docnames:                    pattern = os.path.join(self.srcdir, docname) + '.*'                    files = [relpath(f, self.srcdir) for f in glob(pattern)]                    logger.warning(__('multiple files found for the document "%s": %r\n'                                      'Use %r for the build.'),                                   docname, files, self.doc2path(docname), once=True)                elif os.access(os.path.join(self.srcdir, filename), os.R_OK):                     self.docnames.add(docname)                 else:                     logger.warning(__("document not readable. Ignored."), location=docname)diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py-- a/sphinx/util/logging.py++ b/sphinx/util/logging.py


Question: Files with same name but different extensions leads to unexpected behaviour Describe the bug If there are multiple files with the same name but different file extensions; sphinx will silently choose only one to parse: To Reproduce Steps to reproduce the behavior: Given I have an extension installed to parse with: This will actually include in the document, not Expected behavior A clear and concise description of what you expected to happen. Ideally you would have a config option to specify the order of preference for file extensions, or if not set, a warning would be logged. Your project Link to your sphinx project, or attach zipped small project sample. First noted in: Screenshots If applicable, add screenshots to help explain your problem. Environment info OS: Mac Python version: 3.7.6 Sphinx version: 2.4.4 Sphinx extensions: Additional context Add any other context about the problem here. [e.g. URL or Ticket]

class SphinxLoggerAdapter(logging.LoggerAdapter):     """LoggerAdapter allowing ``type`` and ``subtype`` keywords."""<ins>    KEYWORDS = ['type', 'subtype', 'location', 'nonl', 'color', 'once']</ins>      def log(self, level: Union[int, str], msg: str, *args: Any, **kwargs: Any) -> None:         if isinstance(level, int):


Question: Files with same name but different extensions leads to unexpected behaviour Describe the bug If there are multiple files with the same name but different file extensions; sphinx will silently choose only one to parse: To Reproduce Steps to reproduce the behavior: Given I have an extension installed to parse with: This will actually include in the document, not Expected behavior A clear and concise description of what you expected to happen. Ideally you would have a config option to specify the order of preference for file extensions, or if not set, a warning would be logged. Your project Link to your sphinx project, or attach zipped small project sample. First noted in: Screenshots If applicable, add screenshots to help explain your problem. Environment info OS: Mac Python version: 3.7.6 Sphinx version: 2.4.4 Sphinx extensions: Additional context Add any other context about the problem here. [e.g. URL or Ticket]

def process(self, msg: str, kwargs: Dict) -> Tuple[str, Dict]:  # type: ignore         extra = kwargs.setdefault('extra', {})        if 'type' in kwargs:            extra['type'] = kwargs.pop('type')        if 'subtype' in kwargs:            extra['subtype'] = kwargs.pop('subtype')        if 'location' in kwargs:            extra['location'] = kwargs.pop('location')        if 'nonl' in kwargs:            extra['nonl'] = kwargs.pop('nonl')        if 'color' in kwargs:            extra['color'] = kwargs.pop('color')        for keyword in self.KEYWORDS:            if keyword in kwargs:                extra[keyword] = kwargs.pop(keyword)          return msg, kwargs


Question: Files with same name but different extensions leads to unexpected behaviour Describe the bug If there are multiple files with the same name but different file extensions; sphinx will silently choose only one to parse: To Reproduce Steps to reproduce the behavior: Given I have an extension installed to parse with: This will actually include in the document, not Expected behavior A clear and concise description of what you expected to happen. Ideally you would have a config option to specify the order of preference for file extensions, or if not set, a warning would be logged. Your project Link to your sphinx project, or attach zipped small project sample. First noted in: Screenshots If applicable, add screenshots to help explain your problem. Environment info OS: Mac Python version: 3.7.6 Sphinx version: 2.4.4 Sphinx extensions: Additional context Add any other context about the problem here. [e.g. URL or Ticket]

return True  <ins>class OnceFilter(logging.Filter):    """Show the message only once."""    def __init__(self, name: str = '') -> None:        super().__init__(name)        self.messages = {}  # type: Dict[str, List]    def filter(self, record: logging.LogRecord) -> bool:        once = getattr(record, 'once', '')        if not once:            return True        else:            params = self.messages.setdefault(record.msg, [])            if record.args in params:                return False            params.append(record.args)            return True</ins> class SphinxLogRecordTranslator(logging.Filter):     """Converts a log record to one Sphinx expects


Question: Files with same name but different extensions leads to unexpected behaviour Describe the bug If there are multiple files with the same name but different file extensions; sphinx will silently choose only one to parse: To Reproduce Steps to reproduce the behavior: Given I have an extension installed to parse with: This will actually include in the document, not Expected behavior A clear and concise description of what you expected to happen. Ideally you would have a config option to specify the order of preference for file extensions, or if not set, a warning would be logged. Your project Link to your sphinx project, or attach zipped small project sample. First noted in: Screenshots If applicable, add screenshots to help explain your problem. Environment info OS: Mac Python version: 3.7.6 Sphinx version: 2.4.4 Sphinx extensions: Additional context Add any other context about the problem here. [e.g. URL or Ticket]

warning_handler.addFilter(WarningSuppressor(app))     warning_handler.addFilter(WarningLogRecordTranslator(app))     warning_handler.addFilter(WarningIsErrorFilter(app))<ins>    warning_handler.addFilter(OnceFilter())</ins>     warning_handler.setLevel(logging.WARNING)     warning_handler.setFormatter(ColorizeFormatter())


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

signode: desc_signature) -> None:         modname = self.options.get('module', self.env.ref_context.get('py:module'))         fullname = (modname + '.' if modname else '') + name_cls[0]        node_id = make_id(self.env, self.state.document, modname or '', name_cls[0])        node_id = make_id(self.env, self.state.document, '', fullname)         signode['ids'].append(node_id)          # Assign old styled node_id(fullname) not to break old hyperlinks (if possible)diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py-- a/sphinx/util/nodes.py++ b/sphinx/util/nodes.py


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

"""  import re<ins>import unicodedata</ins> import warnings from typing import Any, Callable, Iterable, List, Set, Tuple from typing import cast


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

return tree  <ins>def _make_id(string: str) -> str:    """Convert `string` into an identifier and return it.    This function is a modified version of ``docutils.nodes.make_id()`` of    docutils-0.16.    Changes:    * Allow to use dots (".") and underscores ("_") for an identifier      without a leading character.    # Author: David Goodger <goodger@python.org>    # Maintainer: docutils-develop@lists.sourceforge.net    # Copyright: This module has been placed in the public domain.    """    id = string.lower()    id = id.translate(_non_id_translate_digraphs)    id = id.translate(_non_id_translate)    # get rid of non-ascii characters.    # 'ascii' lowercase to prevent problems with turkish locale.    id = unicodedata.normalize('NFKD', id).encode('ascii', 'ignore').decode('ascii')    # shrink runs of whitespace and replace by hyphen    id = _non_id_chars.sub('-', ' '.join(id.split()))    id = _non_id_at_ends.sub('', id)    return str(id)_non_id_chars = re.compile('[^a-z0-9._]+')_non_id_at_ends = re.compile('^[-0-9._]+|-+$')_non_id_translate = {    0x00f8: u'o',       # o with stroke    0x0111: u'd',       # d with stroke    0x0127: u'h',       # h with stroke    0x0131: u'i',       # dotless i    0x0142: u'l',       # l with stroke    0x0167: u't',       # t with stroke    0x0180: u'b',       # b with stroke    0x0183: u'b',       # b with topbar    0x0188: u'c',       # c with hook    0x018c: u'd',       # d with topbar    0x0192: u'f',       # f with hook    0x0199: u'k',       # k with hook    0x019a: u'l',       # l with bar    0x019e: u'n',       # n with long right leg    0x01a5: u'p',       # p with hook    0x01ab: u't',       # t with palatal hook    0x01ad: u't',       # t with hook    0x01b4: u'y',       # y with hook    0x01b6: u'z',       # z with stroke    0x01e5: u'g',       # g with stroke    0x0225: u'z',       # z with hook    0x0234: u'l',       # l with curl    0x0235: u'n',       # n with curl    0x0236: u't',       # t with curl    0x0237: u'j',       # dotless j    0x023c: u'c',       # c with stroke    0x023f: u's',       # s with swash tail    0x0240: u'z',       # z with swash tail    0x0247: u'e',       # e with stroke    0x0249: u'j',       # j with stroke    0x024b: u'q',       # q with hook tail    0x024d: u'r',       # r with stroke    0x024f: u'y',       # y with stroke}_non_id_translate_digraphs = {    0x00df: u'sz',      # ligature sz    0x00e6: u'ae',      # ae    0x0153: u'oe',      # ligature oe    0x0238: u'db',      # db digraph    0x0239: u'qp',      # qp digraph}</ins> def make_id(env: "BuildEnvironment", document: nodes.document,             prefix: str = '', term: str = None) -> str:     """Generate an appropriate node_id for given *prefix* and *term*."""


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

# try to generate node_id by *term*     if prefix and term:        node_id = nodes.make_id(idformat % term)        node_id = _make_id(idformat % term)         if node_id == prefix:             # *term* is not good to generate a node_id.             node_id = None     elif term:        node_id = nodes.make_id(term)        node_id = _make_id(term)         if node_id == '':             node_id = None  # fallback to None


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

Some readers crash because they interpret the part as a         transport protocol specification.         """<ins>        def update_node_id(node: Element) -> None:            """Update IDs of given *node*."""            new_ids = []            for node_id in node['ids']:                new_id = self.fix_fragment('', node_id)                if new_id not in new_ids:                    new_ids.append(new_id)            node['ids'] = new_ids</ins>         for reference in tree.traverse(nodes.reference):             if 'refuri' in reference:                 m = self.refuri_re.match(reference['refuri'])


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

reference['refid'] = self.fix_fragment('', reference['refid'])          for target in tree.traverse(nodes.target):            for i, node_id in enumerate(target['ids']):                if ':' in node_id:                    target['ids'][i] = self.fix_fragment('', node_id)            update_node_id(target)              next_node = target.next_node(ascend=True)  # type: Node             if isinstance(next_node, nodes.Element):                for i, node_id in enumerate(next_node['ids']):                    if ':' in node_id:                        next_node['ids'][i] = self.fix_fragment('', node_id)                update_node_id(next_node)          for desc_signature in tree.traverse(addnodes.desc_signature):            ids = desc_signature.attributes['ids']            newids = []            for id in ids:                newids.append(self.fix_fragment('', id))            desc_signature.attributes['ids'] = newids            update_node_id(desc_signature)      def add_visible_links(self, tree: nodes.document, show_urls: str = 'inline') -> None:         """Add visible link targets for external links"""diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py-- a/sphinx/util/nodes.py++ b/sphinx/util/nodes.py


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

Changes: <ins>    * Allow to use capital alphabet characters</ins>     * Allow to use dots (".") and underscores ("_") for an identifier       without a leading character.


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

# Maintainer: docutils-develop@lists.sourceforge.net     # Copyright: This module has been placed in the public domain.     """    id = string.lower()    id = id.translate(_non_id_translate_digraphs)    id = string.translate(_non_id_translate_digraphs)     id = id.translate(_non_id_translate)     # get rid of non-ascii characters.     # 'ascii' lowercase to prevent problems with turkish locale.


Question: Breaking change to Python domain IDs Describe the bug Previously, anchors for Python functions were using underscores, changed this to dashes. To Reproduce Document some Python function whose name contains underscores: Expected behavior This used to create a fragment identifier , but since this creates . Your project This breaks links to python functions when used with : Apart from that all links (containing underscores) from external sites to Python API docs created by Sphinx (which I guess are a lot) will break!

return str(id)  _non_id_chars = re.compile('[^a-z0-9._]+')_non_id_chars = re.compile('[^a-zA-Z0-9._]+') _non_id_at_ends = re.compile('^[-0-9._]+|-+$') _non_id_translate = {     0x00f8: u'o',       # o with stroke


Question: The index directive with "builtin" type generates different index entry than the function directive and generate similar but different index entries. The former generates: The latter generates: Differences: are or not after the name of the function. are or not around "built-in function". takes one or two lines. "max" is a link or not. Link: This issue was reported on the Python bug tracker: Would be nice to unify and merge index entries generated by "function" and "index".

def needs_arglist(self) -> bool:         return True     def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:    def add_target_and_index(self, name_cls: Tuple[str, str], sig: str,                             signode: desc_signature) -> None:        super().add_target_and_index(name_cls, sig, signode)        modname = self.options.get('module', self.env.ref_context.get('py:module'))        node_id = signode['ids'][0]         name, cls = name_cls         if modname:            return _('%s() (in module %s)') % (name, modname)            text = _('%s() (in module %s)') % (name, modname)            self.indexnode['entries'].append(('single', text, node_id, '', None))         else:            return _('%s() (built-in function)') % name            text = '%s; %s()' % (pairindextypes['builtin'], name)            self.indexnode['entries'].append(('pair', text, node_id, '', None))    def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:        # add index in own add_target_and_index() instead.        return None   class PyDecoratorFunction(PyFunction):


Question: The index directive with "builtin" type generates different index entry than the function directive and generate similar but different index entries. The former generates: The latter generates: Differences: are or not after the name of the function. are or not around "built-in function". takes one or two lines. "max" is a link or not. Link: This issue was reported on the Python bug tracker: Would be nice to unify and merge index entries generated by "function" and "index".

# the platform and synopsis aren't printed; in fact, they are only             # used in the modindex currently             ret.append(target)            indextext = _('%s (module)') % modname            inode = addnodes.index(entries=[('single', indextext, node_id, '', None)])            indextext = '%s; %s' % (pairindextypes['module'], modname)            inode = addnodes.index(entries=[('pair', indextext, node_id, '', None)])             ret.append(inode)         return ret


Question: glossary duplicate term with a different case Describe the bug To Reproduce Steps to reproduce the behavior: Expected behavior MySQL != mysql term right ? Your project Environment info OS: Unix Python version: 3.6 Sphinx version: 3.0.0 Additional context Did occur some hours ago, maybe you just released the version https://travis-

term['ids'].append(node_id)      std = cast(StandardDomain, env.get_domain('std'))    std.note_object('term', termtext.lower(), node_id, location=term)    std.note_object('term', termtext, node_id, location=term)      # add an index entry too     indexnode = addnodes.index()


Question: glossary duplicate term with a different case Describe the bug To Reproduce Steps to reproduce the behavior: Expected behavior MySQL != mysql term right ? Your project Environment info OS: Unix Python version: 3.6 Sphinx version: 3.0.0 Additional context Did occur some hours ago, maybe you just released the version https://travis-

# links to tokens in grammar productions         'token':   TokenXRefRole(),         # links to terms in glossary        'term':    XRefRole(lowercase=True, innernodeclass=nodes.inline,        'term':    XRefRole(innernodeclass=nodes.inline,                             warn_dangling=True),         # links to headings or arbitrary labels         'ref':     XRefRole(lowercase=True, innernodeclass=nodes.inline,


Question: Inconsistent handling of None by Describe the bug With , a function that returns generates a clickable link to . With , the in the signature is not clickable. To Reproduce Steps to reproduce the behavior: On running the above reproducer, note that the last two lines are: This contains a link from to the docs, but not one from to the docs. If you uncomment the line in the reproducer script and rerun it, you'll instead see: Expected behavior That in a type hint links to the documentation for the singleton regardless of whether 'description' or 'signature' mode is used. Environment info OS: Linux 4.4.0 Python version: 3.8.1 Sphinx version: 3.1.0.dev20200408 Sphinx extensions: , Additional context I installed a version of Sphinx that contains the fix for using:

def _parse_annotation(annotation: str) -> List[Node]:     """Parse type annotation."""     def make_xref(text: str) -> addnodes.pending_xref:        if text == 'None':            reftype = 'obj'        else:            reftype = 'class'         return pending_xref('', nodes.Text(text),                            refdomain='py', reftype='class', reftarget=text)                            refdomain='py', reftype=reftype, reftarget=text)      def unparse(node: ast.AST) -> List[Node]:         if isinstance(node, ast.Attribute):


Question: for empty tuple type annotation Describe the bug Following notation for empty tuple from like I get To Reproduce Steps to reproduce the behavior: contents of snippet to module and set it to be explorable by sphinx. dependencies, in my : docs. Expected behavior Docs are built and there is with valid type annotations. Your project Environment info OS: Windows 10, but also reproduces on . Python version: 3.8.0 Sphinx version: 3.0.1 Sphinx extensions:

result.append(addnodes.desc_sig_punctuation('', ']'))             return result         elif isinstance(node, ast.Tuple):            result = []            for elem in node.elts:                result.extend(unparse(elem))                result.append(addnodes.desc_sig_punctuation('', ', '))            result.pop()            if node.elts:                result = []                for elem in node.elts:                    result.extend(unparse(elem))                    result.append(addnodes.desc_sig_punctuation('', ', '))                result.pop()            else:                result = [addnodes.desc_sig_punctuation('', '('),                          addnodes.desc_sig_punctuation('', ')')]             return result         else:             raise SyntaxError  # unsupported syntaxdiff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py-- a/sphinx/pycode/ast.py++ b/sphinx/pycode/ast.py


Question: for empty tuple type annotation Describe the bug Following notation for empty tuple from like I get To Reproduce Steps to reproduce the behavior: contents of snippet to module and set it to be explorable by sphinx. dependencies, in my : docs. Expected behavior Docs are built and there is with valid type annotations. Your project Environment info OS: Windows 10, but also reproduces on . Python version: 3.8.0 Sphinx version: 3.0.1 Sphinx extensions:

elif isinstance(node, ast.UnaryOp):         return "%s %s" % (unparse(node.op), unparse(node.operand))     elif isinstance(node, ast.Tuple):        return ", ".join(unparse(e) for e in node.elts)        if node.elts:            return ", ".join(unparse(e) for e in node.elts)        else:            return "()"     elif sys.version_info > (3, 6) and isinstance(node, ast.Constant):         # this branch should be placed at last         return repr(node.value)


Question: glossary duplicate term with a different case Describe the bug To Reproduce Steps to reproduce the behavior: Expected behavior MySQL != mysql term right ? Your project Environment info OS: Unix Python version: 3.6 Sphinx version: 3.0.0 Additional context Did occur some hours ago, maybe you just released the version https://travis-

RemovedInSphinx40Warning)             domain = env.get_domain('citation')             return domain.resolve_xref(env, fromdocname, builder, typ, target, node, contnode)<ins>        elif typ == 'term':            resolver = self._resolve_term_xref</ins>         else:             resolver = self._resolve_obj_xref


Question: glossary duplicate term with a different case Describe the bug To Reproduce Steps to reproduce the behavior: Expected behavior MySQL != mysql term right ? Your project Environment info OS: Unix Python version: 3.6 Sphinx version: 3.0.0 Additional context Did occur some hours ago, maybe you just released the version https://travis-

return make_refnode(builder, fromdocname, docname,                             labelid, contnode) <ins>    def _resolve_term_xref(self, env: "BuildEnvironment", fromdocname: str,                           builder: "Builder", typ: str, target: str,                           node: pending_xref, contnode: Element) -> Element:        result = self._resolve_obj_xref(env, fromdocname, builder, typ,                                        target, node, contnode)        if result:            return result        else:            for objtype, term in self.objects:                if objtype == 'term' and term.lower() == target.lower():                    docname, labelid = self.objects[objtype, term]                    logger.warning(__('term %s not found in case sensitive match.'                                      'made a reference to %s instead.'),                                   target, term, location=node, type='ref', subtype='term')                    break            else:                docname, labelid = '', ''            if not docname:                return None            return make_refnode(builder, fromdocname, docname,                                labelid, contnode)</ins>     def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str,                           builder: "Builder", typ: str, target: str,                           node: pending_xref, contnode: Element) -> Element:


Question: Decorated inherited method has no documentation Describe the bug If an inherited method has a decorator, it does not inherit the parent's doc. To Reproduce Expected behavior Both methods should be documented Environment info OS: Linux (Arch) Python version: 3.6 Sphinx version: 2.1.2 Sphinx extensions: [] Additional context Related to but calls so it should work.

% self.__class__.__name__,                           RemovedInSphinx40Warning)         docstring = getdoc(self.object, self.get_attr,                           self.env.config.autodoc_inherit_docstrings)                           self.env.config.autodoc_inherit_docstrings,                           self.parent, self.object_name)         if docstring:             tab_width = self.directive.state.document.settings.tab_width             return [prepare_docstring(docstring, ignore, tab_width)]


Question: Decorated inherited method has no documentation Describe the bug If an inherited method has a decorator, it does not inherit the parent's doc. To Reproduce Expected behavior Both methods should be documented Environment info OS: Linux (Arch) Python version: 3.6 Sphinx version: 2.1.2 Sphinx extensions: [] Additional context Related to but calls so it should work.

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


Question: Decorated inherited method has no documentation Describe the bug If an inherited method has a decorator, it does not inherit the parent's doc. To Reproduce Expected behavior Both methods should be documented Environment info OS: Linux (Arch) Python version: 3.6 Sphinx version: 2.1.2 Sphinx extensions: [] Additional context Related to but calls so it should work.

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


Question: Decorated inherited method has no documentation Describe the bug If an inherited method has a decorator, it does not inherit the parent's doc. To Reproduce Expected behavior Both methods should be documented Environment info OS: Linux (Arch) Python version: 3.6 Sphinx version: 2.1.2 Sphinx extensions: [] Additional context Related to but calls so it should work.

# try __new__                 __new__ = self.get_attr(self.object, '__new__', None)                 initdocstring = getdoc(__new__, self.get_attr,                                       self.env.config.autodoc_inherit_docstrings)                                       self.env.config.autodoc_inherit_docstrings,                                       self.parent, self.object_name)                 # 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: Decorated inherited method has no documentation Describe the bug If an inherited method has a decorator, it does not inherit the parent's doc. To Reproduce Expected behavior Both methods should be documented Environment info OS: Linux (Arch) Python version: 3.6 Sphinx version: 2.1.2 Sphinx extensions: [] Additional context Related to but calls so it should work.

def getdoc(obj: Any, attrgetter: Callable = safe_getattr,           allow_inherited: bool = False) -> str:           allow_inherited: bool = False, cls: Any = None, name: str = None) -> str:     """Get the docstring for the object.      This tries to obtain the docstring for some kind of objects additionally:      * partial functions     * inherited docstring    * inherited decorated methods     """     doc = attrgetter(obj, '__doc__', None)     if ispartial(obj) and doc == obj.__class__.__doc__:


Question: Decorated inherited method has no documentation Describe the bug If an inherited method has a decorator, it does not inherit the parent's doc. To Reproduce Expected behavior Both methods should be documented Environment info OS: Linux (Arch) Python version: 3.6 Sphinx version: 2.1.2 Sphinx extensions: [] Additional context Related to but calls so it should work.

elif doc is None and allow_inherited:         doc = inspect.getdoc(obj) <ins>        if doc is None and cls:            # 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__', []):                meth = safe_getattr(basecls, name, None)                if meth:                    doc = inspect.getdoc(meth)                    if doc:                        break</ins>     return doc


Question: BUG: Autosummary links broken in master As of commit (according to ) sphinx-gallery builds of a are failing where references to objects are no longer usable: I wondered if it was due to , but we explicitly have so I don't think so. I'll keep working on boiling this down to a more minimal example. But if anyone wants to try in the meantime, something like this should work:

except TemplateNotFound:             return False     def render(self, objtype: str, context: Dict) -> str:    def render(self, template_name: str, context: Dict) -> str:         """Render a template file."""        if objtype.endswith('.rst'):            # old styled: template_name is given            warnings.warn('AutosummaryRenderer.render() takes an object type as an argument.',                          RemovedInSphinx50Warning, stacklevel=2)            return self.env.get_template(objtype).render(context)        if template_name.endswith('.rst'):            template = self.env.get_template(template_name)         else:            # objtype is given            # objtype is given as template_name             try:                template = self.env.get_template('autosummary/%s.rst' % objtype)                template = self.env.get_template('autosummary/%s.rst' % template_name)             except TemplateNotFound:                 # fallback to base.rst                 template = self.env.get_template('autosummary/base.rst')             return template.render(context)        return template.render(context)   # -- Generating output ---------------------------------------------------------


Question: BUG: Autosummary links broken in master As of commit (according to ) sphinx-gallery builds of a are failing where references to objects are no longer usable: I wondered if it was due to , but we explicitly have so I don't think so. I'll keep working on boiling this down to a more minimal example. But if anyone wants to try in the meantime, something like this should work:

ns['objtype'] = doc.objtype     ns['underline'] = len(name) * '='     return template.render(doc.objtype, ns)    if template_name:        return template.render(template_name, ns)    else:        return template.render(doc.objtype, ns)   def generate_autosummary_docs(sources: List[str], output_dir: str = None,


Question: Convert :kbd: to nested <kbdHTML elements Is your feature request related to a problem? Please describe. describes "a sequence of keystrokes". Sphinx converts it to a single  element: becomes Describe the solution you'd like Potentially sphinx could parse the value and convert it to individual (or nested) elements, which is what as a way to represent key combinations. Something like: Describe alternatives you've considered Alternatively the sphinx user could rewrite their markup: Related

# load default math renderer     app.setup_extension('sphinx.ext.mathjax')     # load transforms for HTML builder    app.setup_extension('sphinx.builders.html.transforms')     return {         'version': 'builtin',         'parallel_read_safe': True,diff --git a/sphinx/builders/html/transforms.py b/sphinx/builders/html/transforms.pynew file mode 100644-- /dev/null++ b/sphinx/builders/html/transforms.py


Question: Convert :kbd: to nested <kbdHTML elements Is your feature request related to a problem? Please describe. describes "a sequence of keystrokes". Sphinx converts it to a single  element: becomes Describe the solution you'd like Potentially sphinx could parse the value and convert it to individual (or nested) elements, which is what as a way to represent key combinations. Something like: Describe alternatives you've considered Alternatively the sphinx user could rewrite their markup: Related

"""    sphinx.builders.html.transforms    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    Transforms for HTML builder.    :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.    :license: BSD, see LICENSE for details."""import refrom typing import Any, Dictfrom docutils import nodesfrom sphinx.application import Sphinxfrom sphinx.transforms.post_transforms import SphinxPostTransformfrom sphinx.util.nodes import NodeMatcherclass KeyboardTransform(SphinxPostTransform):    """Transform :kbd: role to more detailed form.    Before::        <literal class="kbd">            Control-x    After::        <literal class="kbd">            <literal class="kbd">                Control            -            <literal class="kbd">                x    """    default_priority = 400    builders = ('html',)    pattern = re.compile(r'(-|\+|\^|\s+)')    def run(self, **kwargs: Any) -> None:        matcher = NodeMatcher(nodes.literal, classes=["kbd"])        for node in self.document.traverse(matcher):  # type: nodes.literal            parts = self.pattern.split(node[-1].astext())            if len(parts) == 1:                continue            node.pop()            while parts:                key = parts.pop(0)                node += nodes.literal('', key, classes=["kbd"])                try:                    # key separator (ex. -, +, ^)                    sep = parts.pop(0)                    node += nodes.Text(sep)                except IndexError:                    passdef setup(app: Sphinx) -> Dict[str, Any]:    app.add_post_transform(KeyboardTransform)    return {        'version': 'builtin',        'parallel_read_safe': True,        'parallel_write_safe': True,    }diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py-- a/sphinx/util/nodes.py++ b/sphinx/util/nodes.py


Question: Convert :kbd: to nested <kbdHTML elements Is your feature request related to a problem? Please describe. describes "a sequence of keystrokes". Sphinx converts it to a single  element: becomes Describe the solution you'd like Potentially sphinx could parse the value and convert it to individual (or nested) elements, which is what as a way to represent key combinations. Something like: Describe alternatives you've considered Alternatively the sphinx user could rewrite their markup: Related

# => [<reference ...>, <reference ...>, ...]     """     def __init__(self, *classes: "Type[Node]", **attrs: Any) -> None:        self.classes = classes    def __init__(self, *node_classes: "Type[Node]", **attrs: Any) -> None:        self.classes = node_classes         self.attrs = attrs      def match(self, node: Node) -> bool:


Question: py domain: Change a type annotation for variables to a hyperlink Is your feature request related to a problem? Please describe. py domain: Change a type annotation for variables to a hyperlink Describe the solution you'd like option was to python directives since 2.x. But it has been represented as mere text. It must be useful if it is converted to a hyperlink to the type definition. Describe alternatives you've considered No Additional context No

('deprecated', bool)])  def _parse_annotation(annotation: str) -> List[Node]:    """Parse type annotation."""    def make_xref(text: str) -> addnodes.pending_xref:        if text == 'None':            reftype = 'obj'        else:            reftype = 'class'def type_to_xref(text: str) -> addnodes.pending_xref:    """Convert a type string to a cross reference node."""    if text == 'None':        reftype = 'obj'    else:        reftype = 'class'         return pending_xref('', nodes.Text(text),                            refdomain='py', reftype=reftype, reftarget=text)    return pending_xref('', nodes.Text(text),                        refdomain='py', reftype=reftype, reftarget=text) def _parse_annotation(annotation: str) -> List[Node]:    """Parse type annotation."""     def unparse(node: ast.AST) -> List[Node]:         if isinstance(node, ast.Attribute):             return [nodes.Text("%s.%s" % (unparse(node.value)[0], node.attr))]


Question: py domain: Change a type annotation for variables to a hyperlink Is your feature request related to a problem? Please describe. py domain: Change a type annotation for variables to a hyperlink Describe the solution you'd like option was to python directives since 2.x. But it has been represented as mere text. It must be useful if it is converted to a hyperlink to the type definition. Describe alternatives you've considered No Additional context No

result = unparse(tree)         for i, node in enumerate(result):             if isinstance(node, nodes.Text):                result[i] = make_xref(str(node))                result[i] = type_to_xref(str(node))         return result     except SyntaxError:        return [make_xref(annotation)]        return [type_to_xref(annotation)]   def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist:


Question: py domain: Change a type annotation for variables to a hyperlink Is your feature request related to a problem? Please describe. py domain: Change a type annotation for variables to a hyperlink Describe the solution you'd like option was to python directives since 2.x. But it has been represented as mere text. It must be useful if it is converted to a hyperlink to the type definition. Describe alternatives you've considered No Additional context No

typ = self.options.get('type')         if typ:            signode += addnodes.desc_annotation(typ, ': ' + typ)            signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), type_to_xref(typ))          value = self.options.get('value')         if value:


Question: py domain: Change a type annotation for variables to a hyperlink Is your feature request related to a problem? Please describe. py domain: Change a type annotation for variables to a hyperlink Describe the solution you'd like option was to python directives since 2.x. But it has been represented as mere text. It must be useful if it is converted to a hyperlink to the type definition. Describe alternatives you've considered No Additional context No


Question: Sphinx, unlike Docutils, incorrectly renders consecutive backslashes Describe the bug Sphinx incorrectly renders four or more consecutive backslashes. In pure Docutils, they are renderer properly according with RST spec. To Reproduce The following snippet demonstrantes buggy rendering. Expected behavior Two backslashes should be rendered as . Three still as . Four and five as . Six as and so on. This is how it works in Docutils. Screenshots ! Environment info OS: Linux Python version: 3.6 Sphinx version: 3.0.2 Sphinx extensions: none

from sphinx.config import Config from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.locale import _, __<ins>from sphinx.util import docutils</ins> from sphinx.util import logging from sphinx.util.docutils import new_document from sphinx.util.i18n import format_date


Question: Sphinx, unlike Docutils, incorrectly renders consecutive backslashes Describe the bug Sphinx incorrectly renders four or more consecutive backslashes. In pure Docutils, they are renderer properly according with RST spec. To Reproduce The following snippet demonstrantes buggy rendering. Expected behavior Two backslashes should be rendered as . Three still as . Four and five as . Six as and so on. This is how it works in Docutils. Screenshots ! Environment info OS: Linux Python version: 3.6 Sphinx version: 3.0.2 Sphinx extensions: none

def get_tokens(self, txtnodes: List[Text]) -> Generator[Tuple[str, str], None, None]:         # A generator that yields ``(texttype, nodetext)`` tuples for a list         # of "Text" nodes (interface to ``smartquotes.educate_tokens()``).        texttype = {True: 'literal',  # "literal" text is not changed:                    False: 'plain'}         for txtnode in txtnodes:            notsmartquotable = not is_smartquotable(txtnode)            yield (texttype[notsmartquotable], txtnode.astext())            if is_smartquotable(txtnode):                if docutils.__version_info__ >= (0, 16):                    # SmartQuotes uses backslash escapes instead of null-escapes                    text = re.sub(r'(?<=\x00)([-\\\'".`])', r'\\\1', str(txtnode))                else:                    text = txtnode.astext()                yield ('plain', text)            else:                # skip smart quotes                yield ('literal', txtnode.astext())   class DoctreeReadEvent(SphinxTransform):


Question: autosummary: The members variable for module template contains imported members Describe the bug autosummary: The members variable for module template contains imported members even if autosummaryimportedmembers is False. To Reproduce As a result, I got following output: Expected behavior The template variable should not contain imported members when is False. Your project No Screenshots No Environment info OS: Mac Python version: 3.8.2 Sphinx version: 3.1.0dev Sphinx extensions: Extra tools: No Additional context No

"""  import argparse<ins>import inspect</ins> import locale import os import pkgutil


Question: autosummary: The members variable for module template contains imported members Describe the bug autosummary: The members variable for module template contains imported members even if autosummaryimportedmembers is False. To Reproduce As a result, I got following output: Expected behavior The template variable should not contain imported members when is False. Your project No Screenshots No Environment info OS: Mac Python version: 3.8.2 Sphinx version: 3.1.0dev Sphinx extensions: Extra tools: No Additional context No

# -- Generating output ---------------------------------------------------------  <ins>class ModuleScanner:    def __init__(self, app: Any, obj: Any) -> None:        self.app = app        self.object = obj    def get_object_type(self, name: str, value: Any) -> str:        return get_documenter(self.app, value, self.object).objtype    def is_skipped(self, name: str, value: Any, objtype: str) -> bool:        try:            return self.app.emit_firstresult('autodoc-skip-member', objtype,                                             name, value, False, {})        except Exception as exc:            logger.warning(__('autosummary: failed to determine %r to be documented, '                              'the following exception was raised:\n%s'),                           name, exc, type='autosummary')            return False    def scan(self, imported_members: bool) -> List[str]:        members = []        for name in dir(self.object):            try:                value = safe_getattr(self.object, name)            except AttributeError:                value = None            objtype = self.get_object_type(name, value)            if self.is_skipped(name, value, objtype):                continue            try:                if inspect.ismodule(value):                    imported = True                elif safe_getattr(value, '__module__') != self.object.__name__:                    imported = True                else:                    imported = False            except AttributeError:                imported = False            if imported_members:                # list all members up                members.append(name)            elif imported is False:                # list not-imported members up                members.append(name)        return members</ins> def generate_autosummary_content(name: str, obj: Any, parent: Any,                                  template: AutosummaryRenderer, template_name: str,                                  imported_members: bool, app: Any,


Question: autosummary: The members variable for module template contains imported members Describe the bug autosummary: The members variable for module template contains imported members even if autosummaryimportedmembers is False. To Reproduce As a result, I got following output: Expected behavior The template variable should not contain imported members when is False. Your project No Screenshots No Environment info OS: Mac Python version: 3.8.2 Sphinx version: 3.1.0dev Sphinx extensions: Extra tools: No Additional context No

ns.update(context)      if doc.objtype == 'module':        ns['members'] = dir(obj)        scanner = ModuleScanner(app, obj)        ns['members'] = scanner.scan(imported_members)         ns['functions'], ns['all_functions'] = \             get_members(obj, {'function'}, imported=imported_members)         ns['classes'], ns['all_classes'] = \


Question: overescaped trailing underscore on attribute with napoleon Describe the bug Attribute name shows up as in the html (visible backslash) with napoleon. To Reproduce Steps to reproduce the behavior: empty contains run add to extensions in add to PYTHONPATH=. make clean html open in web browser and see the ugly backslash. Expected behavior No backslash, a similar output to what I get for (the type shows up differently as well, but that's not the point here) Older versions like 2.4.3 look ok to me. Environment info OS: Linux debian testing Python version: 3.8.3 Sphinx version: 3.0.4 Sphinx extensions: , Extra tools:

return [line[min_indent:] for line in lines]      def _escape_args_and_kwargs(self, name: str) -> str:        if name.endswith('_'):        if name.endswith('_') and getattr(self._config, 'strip_signature_backslash', False):             name = name[:-1] + r'\_'          if name[:2] == '**':


Question: autodocdocstringsignature with overloaded methods When using swig to wrap C++ classes for python, if they have overloaded methods, I believe the convention is to place the signatures for each of the overloaded C++ methods at the start of the docstring. Currently, can only pick up the first one. It would be nice to be able to pick up all of them.

Mixin for FunctionDocumenter and MethodDocumenter to provide the     feature of reading the signature from the docstring.     """    _new_docstrings = None  # type: List[List[str]]    _signatures = None      # type: List[str]      def _find_signature(self, encoding: str = None) -> Tuple[str, str]:         if encoding is not None:             warnings.warn("The 'encoding' argument to autodoc.%s._find_signature() is "                           "deprecated." % self.__class__.__name__,                           RemovedInSphinx40Warning, stacklevel=2)        # candidates of the object name        valid_names = [self.objpath[-1]]  # type: ignore        if isinstance(self, ClassDocumenter):            valid_names.append('__init__')            if hasattr(self.object, '__mro__'):                valid_names.extend(cls.__name__ for cls in self.object.__mro__)         docstrings = self.get_doc()         self._new_docstrings = docstrings[:]        self._signatures = []         result = None         for i, doclines in enumerate(docstrings):            # no lines in docstring, no match            if not doclines:                continue            # match first line of docstring against signature RE            match = py_ext_sig_re.match(doclines[0])            if not match:                continue            exmod, path, base, args, retann = match.groups()            # the base name must match ours            valid_names = [self.objpath[-1]]  # type: ignore            if isinstance(self, ClassDocumenter):                valid_names.append('__init__')                if hasattr(self.object, '__mro__'):                    valid_names.extend(cls.__name__ for cls in self.object.__mro__)            if base not in valid_names:                continue            # re-prepare docstring to ignore more leading indentation            tab_width = self.directive.state.document.settings.tab_width  # type: ignore            self._new_docstrings[i] = prepare_docstring('\n'.join(doclines[1:]),                                                        tabsize=tab_width)            result = args, retann            # don't look any further            break            for j, line in enumerate(doclines):                if not line:                    # no lines in docstring, no match                    break                if line.endswith('\\'):                    multiline = True                    line = line.rstrip('\\').rstrip()                else:                    multiline = False                # match first line of docstring against signature RE                match = py_ext_sig_re.match(line)                if not match:                    continue                exmod, path, base, args, retann = match.groups()                # the base name must match ours                if base not in valid_names:                    continue                # re-prepare docstring to ignore more leading indentation                tab_width = self.directive.state.document.settings.tab_width  # type: ignore                self._new_docstrings[i] = prepare_docstring('\n'.join(doclines[j + 1:]),                                                            tabsize=tab_width)                if result is None:                    # first signature                    result = args, retann                else:                    # subsequent signatures                    self._signatures.append("(%s) -> %s" % (args, retann))                if multiline:                    # the signature have multiple signatures on docstring                    continue                else:                    # don't look any further                    break            if result:                # finish the loop when signature found                break         return result      def get_doc(self, encoding: str = None, ignore: int = None) -> List[List[str]]:


Question: autodocdocstringsignature with overloaded methods When using swig to wrap C++ classes for python, if they have overloaded methods, I believe the convention is to place the signatures for each of the overloaded C++ methods at the start of the docstring. Currently, can only pick up the first one. It would be nice to be able to pick up all of them.

warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."                           % self.__class__.__name__,                           RemovedInSphinx40Warning, stacklevel=2)        lines = getattr(self, '_new_docstrings', None)        if lines is not None:            return lines        if self._new_docstrings is not None:            return self._new_docstrings         return super().get_doc(None, ignore)  # type: ignore      def format_signature(self, **kwargs: Any) -> str:


Question: autodocdocstringsignature with overloaded methods When using swig to wrap C++ classes for python, if they have overloaded methods, I believe the convention is to place the signatures for each of the overloaded C++ methods at the start of the docstring. Currently, can only pick up the first one. It would be nice to be able to pick up all of them.

result = self._find_signature()             if result is not None:                 self.args, self.retann = result        return super().format_signature(**kwargs)  # type: ignore        sig = super().format_signature(**kwargs)  # type: ignore        if self._signatures:            return "\n".join([sig] + self._signatures)        else:            return sig   class DocstringStripSignatureMixin(DocstringSignatureMixin):


Question: autodocdocstringsignature with overloaded methods When using swig to wrap C++ classes for python, if they have overloaded methods, I believe the convention is to place the signatures for each of the overloaded C++ methods at the start of the docstring. Currently, can only pick up the first one. It would be nice to be able to pick up all of them.

documenter = FunctionDocumenter(self.directive, '')                     documenter.object = func<ins>                    documenter.objpath = [None]</ins>                     sigs.append(documenter.format_signature())          return "\n".join(sigs)


Question: The default value for positional only argument has vanished Describe the bug The default value for positional only argument has vanished To Reproduce Build following document: Result: <img width="148" alt=" 2020-05-30 23 43 01" src="https://user-"Expected behavior The default value is shown. Your project No. Environment info OS: Mac Python version: 3.8.2 Sphinx version: 3.1.0dev Sphinx extensions: No Extra tools: No Additional context No

# parameters     args = definition.args    defaults = list(args.defaults)     params = []    if hasattr(args, "posonlyargs"):        posonlyargs = len(args.posonlyargs)  # type: ignore        positionals = posonlyargs + len(args.args)    else:        posonlyargs = 0        positionals = len(args.args)    for _ in range(len(defaults), positionals):        defaults.insert(0, Parameter.empty)      if hasattr(args, "posonlyargs"):        for arg in args.posonlyargs:  # type: ignore        for i, arg in enumerate(args.posonlyargs):  # type: ignore            if defaults[i] is Parameter.empty:                default = Parameter.empty            else:                default = ast_unparse(defaults[i])             annotation = ast_unparse(arg.annotation) or Parameter.empty             params.append(Parameter(arg.arg, Parameter.POSITIONAL_ONLY,                                    annotation=annotation))                                    default=default, annotation=annotation))      for i, arg in enumerate(args.args):        if len(args.args) - i <= len(args.defaults):            default = ast_unparse(args.defaults[-len(args.args) + i])        else:        if defaults[i + posonlyargs] is Parameter.empty:             default = Parameter.empty        else:            default = ast_unparse(defaults[i + posonlyargs])          annotation = ast_unparse(arg.annotation) or Parameter.empty         params.append(Parameter(arg.arg, Parameter.POSITIONAL_OR_KEYWORD,


Question: coverage ext - config to print missing coverage as warning Is your feature request related to a problem? Please describe. I run CI tests with tox and want to test my docs also. I created the following tox env but the problem is that the env does not fail on missing coverage. Describe the solution you'd like My idea is to simply add another config variable like for the extension to not only print the missing coverage to files but also as a warning to stdout (or stderr?) like the builder on broken links. Describe alternatives you've considered I considered writing a script which checks if there is content in the file and returns the appropriate exit code. The script could then be called by after the builder ran. EDIT: Added config name.

from sphinx.builders import Builder from sphinx.locale import __ from sphinx.util import logging<ins>from sphinx.util.console import red  # type: ignore</ins> from sphinx.util.inspect import safe_getattr  logger = logging.getLogger(__name__)


Question: coverage ext - config to print missing coverage as warning Is your feature request related to a problem? Please describe. I run CI tests with tox and want to test my docs also. I created the following tox env but the problem is that the env does not fail on missing coverage. Describe the solution you'd like My idea is to simply add another config variable like for the extension to not only print the missing coverage to files but also as a warning to stdout (or stderr?) like the builder on broken links. Describe alternatives you've considered I considered writing a script which checks if there is content in the file and returns the appropriate exit code. The script could then be called by after the builder ran. EDIT: Added config name.

write_header(op, filename)                 for typ, name in sorted(undoc):                     op.write(' * %-50s [%9s]\n' % (name, typ))<ins>                    if self.config.coverage_show_missing_items:                        if self.app.quiet or self.app.warningiserror:                            logger.warning(__('undocumented c api: %s [%s] in file %s'),                                           name, typ, filename)                        else:                            logger.info(red('undocumented  ') + 'c   ' + 'api       ' +                                        '%-30s' % (name + " [%9s]" % typ) +                                        red(' - in file ') + filename)</ins>                 op.write('\n')      def ignore_pyobj(self, full_name: str) -> bool:


Question: coverage ext - config to print missing coverage as warning Is your feature request related to a problem? Please describe. I run CI tests with tox and want to test my docs also. I created the following tox env but the problem is that the env does not fail on missing coverage. Describe the solution you'd like My idea is to simply add another config variable like for the extension to not only print the missing coverage to files but also as a warning to stdout (or stderr?) like the builder on broken links. Describe alternatives you've considered I considered writing a script which checks if there is content in the file and returns the appropriate exit code. The script could then be called by after the builder ran. EDIT: Added config name.

if undoc['funcs']:                         op.write('Functions:\n')                         op.writelines(' * %s\n' % x for x in undoc['funcs'])                        if self.config.coverage_show_missing_items:                            if self.app.quiet or self.app.warningiserror:                                for func in undoc['funcs']:                                    logger.warning(                                        __('undocumented python function: %s :: %s'),                                        name, func)                            else:                                for func in undoc['funcs']:                                    logger.info(red('undocumented  ') + 'py  ' + 'function  ' +                                                '%-30s' % func + red(' - in module ') + name)                         op.write('\n')                     if undoc['classes']:                         op.write('Classes:\n')                        for name, methods in sorted(                        for class_name, methods in sorted(                                 undoc['classes'].items()):                             if not methods:                                op.write(' * %s\n' % name)                                op.write(' * %s\n' % class_name)                                if self.config.coverage_show_missing_items:                                    if self.app.quiet or self.app.warningiserror:                                        logger.warning(                                            __('undocumented python class: %s :: %s'),                                            name, class_name)                                    else:                                        logger.info(red('undocumented  ') + 'py  ' +                                                    'class     ' + '%-30s' % class_name +                                                    red(' - in module ') + name)                             else:                                op.write(' * %s -- missing methods:\n\n' % name)                                op.write(' * %s -- missing methods:\n\n' % class_name)                                 op.writelines('   - %s\n' % x for x in methods)                                if self.config.coverage_show_missing_items:                                    if self.app.quiet or self.app.warningiserror:                                        for meth in methods:                                            logger.warning(                                                __('undocumented python method:' +                                                   ' %s :: %s :: %s'),                                                name, class_name, meth)                                    else:                                        for meth in methods:                                            logger.info(red('undocumented  ') + 'py  ' +                                                        'method    ' + '%-30s' %                                                        (class_name + '.' + meth) +                                                        red(' - in module ') + name)                         op.write('\n')              if failed:


Question: coverage ext - config to print missing coverage as warning Is your feature request related to a problem? Please describe. I run CI tests with tox and want to test my docs also. I created the following tox env but the problem is that the env does not fail on missing coverage. Describe the solution you'd like My idea is to simply add another config variable like for the extension to not only print the missing coverage to files but also as a warning to stdout (or stderr?) like the builder on broken links. Describe alternatives you've considered I considered writing a script which checks if there is content in the file and returns the appropriate exit code. The script could then be called by after the builder ran. EDIT: Added config name.

app.add_config_value('coverage_ignore_c_items', {}, False)     app.add_config_value('coverage_write_headline', True, False)     app.add_config_value('coverage_skip_undoc_in_source', False, False)<ins>    app.add_config_value('coverage_show_missing_items', False, False)</ins>     return {'version': sphinx.__display_version__, 'parallel_read_safe': True}


Question: Add support for custom HTTP headers @ linkcheck Is your feature request related to a problem? Please describe. Currently, HTTP header is hardcoded: And when I hit servers that require custom headers, the only option is to add those URLs to the ignore list which is what I'd like to avoid. Describe the solution you'd like Make HTTP headers configurable. Describe alternatives you've considered Adding the affected URL to Additional context We have a GitHub Actions badge in README which then gets embedded into Sphinx docs. Running used to work but now it doesn't. After some debugging I discovered that if the HTTP query doesn't have HTTP header, it works. But the header that Sphinx injects causes GitHub's server to respond with . Interestingly, if you open this URL in a browser, it works: Google Chrome sends the following header: .

from html.parser import HTMLParser from os import path from typing import Any, Dict, List, Set, Tuplefrom urllib.parse import unquotefrom urllib.parse import unquote, urlparse  from docutils import nodes from docutils.nodes import Node


Question: Add support for custom HTTP headers @ linkcheck Is your feature request related to a problem? Please describe. Currently, HTTP header is hardcoded: And when I hit servers that require custom headers, the only option is to add those URLs to the ignore list which is what I'd like to avoid. Describe the solution you'd like Make HTTP headers configurable. Describe alternatives you've considered Adding the affected URL to Additional context We have a GitHub Actions badge in README which then gets embedded into Sphinx docs. Running used to work but now it doesn't. After some debugging I discovered that if the HTTP query doesn't have HTTP header, it works. But the header that Sphinx injects causes GitHub's server to respond with . Interestingly, if you open this URL in a browser, it works: Google Chrome sends the following header: .

logger = logging.getLogger(__name__)  <ins>DEFAULT_REQUEST_HEADERS = {    'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',}</ins> class AnchorCheckParser(HTMLParser):     """Specialized HTML parser that looks for a specific anchor."""


Question: Add support for custom HTTP headers @ linkcheck Is your feature request related to a problem? Please describe. Currently, HTTP header is hardcoded: And when I hit servers that require custom headers, the only option is to add those URLs to the ignore list which is what I'd like to avoid. Describe the solution you'd like Make HTTP headers configurable. Describe alternatives you've considered Adding the affected URL to Additional context We have a GitHub Actions badge in README which then gets embedded into Sphinx docs. Running used to work but now it doesn't. After some debugging I discovered that if the HTTP query doesn't have HTTP header, it works. But the header that Sphinx injects causes GitHub's server to respond with . Interestingly, if you open this URL in a browser, it works: Google Chrome sends the following header: .

def check_thread(self) -> None:         kwargs = {             'allow_redirects': True,            'headers': {                'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',            },        }        }  # type: Dict         if self.app.config.linkcheck_timeout:             kwargs['timeout'] = self.app.config.linkcheck_timeout         def get_request_headers() -> Dict:            url = urlparse(uri)            candidates = ["%s://%s" % (url.scheme, url.netloc),                          "%s://%s/" % (url.scheme, url.netloc),                          uri,                          "*"]            for u in candidates:                if u in self.config.linkcheck_request_headers:                    headers = dict(DEFAULT_REQUEST_HEADERS)                    headers.update(self.config.linkcheck_request_headers[u])                    return headers            return {}         def check_uri() -> Tuple[str, str, int]:             # split off anchor             if '#' in uri:


Question: Add support for custom HTTP headers @ linkcheck Is your feature request related to a problem? Please describe. Currently, HTTP header is hardcoded: And when I hit servers that require custom headers, the only option is to add those URLs to the ignore list which is what I'd like to avoid. Describe the solution you'd like Make HTTP headers configurable. Describe alternatives you've considered Adding the affected URL to Additional context We have a GitHub Actions badge in README which then gets embedded into Sphinx docs. Running used to work but now it doesn't. After some debugging I discovered that if the HTTP query doesn't have HTTP header, it works. But the header that Sphinx injects causes GitHub's server to respond with . Interestingly, if you open this URL in a browser, it works: Google Chrome sends the following header: .

else:                 auth_info = None <ins>            # update request headers for the URL            kwargs['headers'] = get_request_headers()</ins>             try:                 if anchor and self.app.config.linkcheck_anchors:                     # Read the whole document and see if #anchor exists


Question: Add support for custom HTTP headers @ linkcheck Is your feature request related to a problem? Please describe. Currently, HTTP header is hardcoded: And when I hit servers that require custom headers, the only option is to add those URLs to the ignore list which is what I'd like to avoid. Describe the solution you'd like Make HTTP headers configurable. Describe alternatives you've considered Adding the affected URL to Additional context We have a GitHub Actions badge in README which then gets embedded into Sphinx docs. Running used to work but now it doesn't. After some debugging I discovered that if the HTTP query doesn't have HTTP header, it works. But the header that Sphinx injects causes GitHub's server to respond with . Interestingly, if you open this URL in a browser, it works: Google Chrome sends the following header: .

app.add_config_value('linkcheck_ignore', [], None)     app.add_config_value('linkcheck_auth', [], None)<ins>    app.add_config_value('linkcheck_request_headers', {}, None)</ins>     app.add_config_value('linkcheck_retries', 1, None)     app.add_config_value('linkcheck_timeout', None, None, [int])     app.add_config_value('linkcheck_workers', 5, None)


Question: Warnings raised on variable and attribute type annotations Describe the bug autodoc signature for non-builtin types raises warning and thus fails nitpicking: To Reproduce Steps to reproduce the behavior: Create a file with the following content: Use sphinx-apidoc to generate an rst file, while enabling autodoc and intersphinx: Make sure the in the Sphinx contains Run with loud warnings and nitpicking: . You will get an error message Expected behavior I'd expect Sphinx to resolve the type annotation and possibly link both classes. Environment info OS: Linux Python version: 3.8.3 Sphinx version: 3.1.0 Sphinx extensions: , Additional context I think the issue stems from the change in which appears to try to lookup the entire type annotation as a single class. Using instead of solves this particular issue: However, it doesn't seem to work with custom classes. Take this snippet for example: This causes the following warning:

typ = self.options.get('type')         if typ:            signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), type_to_xref(typ))            annotations = _parse_annotation(typ)            signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)          value = self.options.get('value')         if value:


Question: Warnings raised on variable and attribute type annotations Describe the bug autodoc signature for non-builtin types raises warning and thus fails nitpicking: To Reproduce Steps to reproduce the behavior: Create a file with the following content: Use sphinx-apidoc to generate an rst file, while enabling autodoc and intersphinx: Make sure the in the Sphinx contains Run with loud warnings and nitpicking: . You will get an error message Expected behavior I'd expect Sphinx to resolve the type annotation and possibly link both classes. Environment info OS: Linux Python version: 3.8.3 Sphinx version: 3.1.0 Sphinx extensions: , Additional context I think the issue stems from the change in which appears to try to lookup the entire type annotation as a single class. Using instead of solves this particular issue: However, it doesn't seem to work with custom classes. Take this snippet for example: This causes the following warning:


Question: regression in 3.1.0 for methods which are s and have a type comment Describe the bug methods decorated with trigger errors similar to this when built with sphinx 3.1.0 (this worked in 3.0.4): To Reproduce Steps to reproduce the behavior: Expected behavior This should work! Your project Screenshots N/A Environment info OS: ubuntu 20.04 Python version: 3.8.2 Sphinx version: 3.1.0 Sphinx extensions: sphinx-rtd-theme, sphinx-prompt Extra tools: N/A Additional context N/A From a bisection, this is the commit which introduced the regression: CC

if 'return' not in obj.__annotations__:                 obj.__annotations__['return'] = type_sig.return_annotation    except KeyError as exc:        logger.warning(__("Failed to update signature for %r: parameter not found: %s"),                       obj, exc)     except NotImplementedError as exc:  # failed to ast.unparse()         logger.warning(__("Failed to parse type_comment for %r: %s"), obj, exc) diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py-- a/sphinx/util/inspect.py++ b/sphinx/util/inspect.py


Question: regression in 3.1.0 for methods which are s and have a type comment Describe the bug methods decorated with trigger errors similar to this when built with sphinx 3.1.0 (this worked in 3.0.4): To Reproduce Steps to reproduce the behavior: Expected behavior This should work! Your project Screenshots N/A Environment info OS: ubuntu 20.04 Python version: 3.8.2 Sphinx version: 3.1.0 Sphinx extensions: sphinx-rtd-theme, sphinx-prompt Extra tools: N/A Additional context N/A From a bisection, this is the commit which introduced the regression: CC

"""  import builtins<ins>import contextlib</ins> import enum import inspect import re


Question: regression in 3.1.0 for methods which are s and have a type comment Describe the bug methods decorated with trigger errors similar to this when built with sphinx 3.1.0 (this worked in 3.0.4): To Reproduce Steps to reproduce the behavior: Expected behavior This should work! Your project Screenshots N/A Environment info OS: ubuntu 20.04 Python version: 3.8.2 Sphinx version: 3.1.0 Sphinx extensions: sphinx-rtd-theme, sphinx-prompt Extra tools: N/A Additional context N/A From a bisection, this is the commit which introduced the regression: CC

return getattr(builtins, name, None) is cls  <ins>def _should_unwrap(subject: Callable) -> bool:    """Check the function should be unwrapped on getting signature."""    if (safe_getattr(subject, '__globals__', None) and            subject.__globals__.get('__name__') == 'contextlib' and  # type: ignore            subject.__globals__.get('__file__') == contextlib.__file__):  # type: ignore        # contextmanger should be unwrapped        return True    return False</ins> def signature(subject: Callable, bound_method: bool = False, follow_wrapped: bool = False               ) -> inspect.Signature:     """Return a Signature object for the given *subject*.


Question: regression in 3.1.0 for methods which are s and have a type comment Describe the bug methods decorated with trigger errors similar to this when built with sphinx 3.1.0 (this worked in 3.0.4): To Reproduce Steps to reproduce the behavior: Expected behavior This should work! Your project Screenshots N/A Environment info OS: ubuntu 20.04 Python version: 3.8.2 Sphinx version: 3.1.0 Sphinx extensions: sphinx-rtd-theme, sphinx-prompt Extra tools: N/A Additional context N/A From a bisection, this is the commit which introduced the regression: CC

"""     try:         try:            signature = inspect.signature(subject, follow_wrapped=follow_wrapped)            if _should_unwrap(subject):                signature = inspect.signature(subject)            else:                signature = inspect.signature(subject, follow_wrapped=follow_wrapped)         except ValueError:             # follow built-in wrappers up (ex. functools.lru_cache)             signature = inspect.signature(subject)


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

from sphinx.roles import SphinxRole, XRefRole from sphinx.util import logging from sphinx.util.cfamily import (    NoOldIdError, ASTBaseBase, verify_description_mode, StringifyTransform,    NoOldIdError, ASTBaseBase, ASTBaseParenExprList,    verify_description_mode, StringifyTransform,     BaseParser, DefinitionError, UnsupportedMultiCharacterCharLiteral,     identifier_re, anon_identifier_re, integer_literal_re, octal_literal_re,     hex_literal_re, binary_literal_re, integers_literal_suffix_re,


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

# Initializer ################################################################################ class ASTParenExprList(ASTBase):class ASTParenExprList(ASTBaseParenExprList):     def __init__(self, exprs: List[ASTExpression]) -> None:         self.exprs = exprs diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py-- a/sphinx/domains/cpp.py++ b/sphinx/domains/cpp.py


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

from sphinx.transforms.post_transforms import ReferencesResolver from sphinx.util import logging from sphinx.util.cfamily import (    NoOldIdError, ASTBaseBase, ASTAttribute, verify_description_mode, StringifyTransform,    NoOldIdError, ASTBaseBase, ASTAttribute, ASTBaseParenExprList,    verify_description_mode, StringifyTransform,     BaseParser, DefinitionError, UnsupportedMultiCharacterCharLiteral,     identifier_re, anon_identifier_re, integer_literal_re, octal_literal_re,     hex_literal_re, binary_literal_re, integers_literal_suffix_re,


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

signode += nodes.Text('...')  class ASTParenExprList(ASTBase):class ASTParenExprList(ASTBaseParenExprList):     def __init__(self, exprs: List[Union[ASTExpression, ASTBracedInitList]]) -> None:         self.exprs = exprs diff --git a/sphinx/util/cfamily.py b/sphinx/util/cfamily.py-- a/sphinx/util/cfamily.py++ b/sphinx/util/cfamily.py


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

import warnings from copy import deepcopy from typing import (    Any, Callable, List, Match, Pattern, Tuple, Union    Any, Callable, List, Match, Optional, Pattern, Tuple, Union )  from docutils import nodes


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

class ASTGnuAttribute(ASTBaseBase):    def __init__(self, name: str, args: Any) -> None:    def __init__(self, name: str, args: Optional["ASTBaseParenExprList"]) -> None:         self.name = name         self.args = args      def _stringify(self, transform: StringifyTransform) -> str:         res = [self.name]         if self.args:            res.append('(')             res.append(transform(self.args))            res.append(')')         return ''.join(res)


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

################################################################################ <ins>class ASTBaseParenExprList(ASTBaseBase):    pass################################################################################</ins>  class UnsupportedMultiCharacterCharLiteral(Exception):     @property


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

while 1:                 if self.match(identifier_re):                     name = self.matched_text                    self.skip_ws()                    if self.skip_string_and_ws('('):                        self.fail('Parameterized GNU style attribute not yet supported.')                    attrs.append(ASTGnuAttribute(name, None))                    # TODO: parse arguments for the attribute                    exprs = self._parse_paren_expression_list()                    attrs.append(ASTGnuAttribute(name, exprs))                 if self.skip_string_and_ws(','):                     continue                 elif self.skip_string_and_ws(')'):


Question: Support for parameterized GNU style attributes on C++ code. Hi folks. My C++ codebase uses GNU attributes for code like Unfortunately, it looks like Sphinx doesn't support them. I'm running Sphinx 3.1.1, though this functionality doesn't appear to have changed in 4. I tried to get clever with the custom attribute support you offer, but can't seem to get that to work either. Is there a right way to do this? I'd honestly be fine having the attributes stripped entirely for doc generation if there isn't another option. Even though I'm bumping up against a sharp edge, I really appreciate Sphinx. Thanks so much for making a useful tool.

return ASTParenAttribute(id, arg)          return None<ins>    def _parse_paren_expression_list(self) -> ASTBaseParenExprList:        raise NotImplementedError</ins>


Question: autodoctypehints = 'descriptions' throws KeyError: 'module' Describe the bug autodoctypehints = 'description' does not work, results in To Reproduce Environment info OS: Linux Python version: 3.5.6 Sphinx version: 3.0.4 Sphinx extensions: , Additional context Full error message: Log file

if objtype == 'class' and app.config.autoclass_content not in ('init', 'both'):         return     signature = cast(addnodes.desc_signature, contentnode.parent[0])    if signature['module']:        fullname = '.'.join([signature['module'], signature['fullname']])    else:        fullname = signature['fullname']    try:        signature = cast(addnodes.desc_signature, contentnode.parent[0])        if signature['module']:            fullname = '.'.join([signature['module'], signature['fullname']])        else:            fullname = signature['fullname']    except KeyError:        # signature node does not have valid context info for the target object        return     annotations = app.env.temp_data.get('annotations', {})     if annotations.get(fullname, {}):         field_lists = [n for n in contentnode if isinstance(n, nodes.field_list)]


Question: Autodoc extension's mock file throws TypeError for generic-typed classes. Describe the bug When building the docs for a generically-typed class, a TypeError is thrown as Autodoc's attempts to concatenate a to a . See the attached log: To Reproduce Observe the docs command fails with a TypeError. Expected behavior Docs can still be built when generics are involved. Your project Environment info OS: Mac 10.15.5 (19F101) Python version: 3.7.7 Sphinx version: 3.1.1 Sphinx extensions: , , , , Additional context This might just be me not knowing how to make Sphinx-friendly generic typing, if that's the case please let me know!

def __mro_entries__(self, bases: Tuple) -> Tuple:         return (self.__class__,)     def __getitem__(self, key: str) -> "_MockObject":        return _make_subclass(key, self.__display_name__, self.__class__)()    def __getitem__(self, key: Any) -> "_MockObject":        return _make_subclass(str(key), self.__display_name__, self.__class__)()      def __getattr__(self, key: str) -> "_MockObject":         return _make_subclass(key, self.__display_name__, self.__class__)()