Question: 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: 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

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-


Question: 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: % 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)]

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.


Question: 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: 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: # 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: 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: 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: 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 ---------------------------------------------------------

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:


Question: 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: # 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

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


Question: """    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: # => [<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: ('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))]

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: 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: 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: 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: 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

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


Question: 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: """  import argparse<ins>import inspect</ins> import locale import os import pkgutil

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


Question: # -- 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: 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: 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] == '**':

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:


Question: 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]]:

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.


Question: 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: 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: documenter = FunctionDocumenter(self.directive, '')                     documenter.object = func<ins>                    documenter.objpath = [None]</ins>                     sigs.append(documenter.format_signature())          return "\n".join(sigs)


Question: # 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,

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


Question: 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__)

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.


Question: 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: 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: 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: 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

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: .


Question: 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: 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: 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: 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: 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:

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: 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: 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

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


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


Question: 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: """     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: 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,

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.


Question: # 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: 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: 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: 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: 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: ################################################################################ <ins>class ASTBaseParenExprList(ASTBaseBase):    pass################################################################################</ins>  class UnsupportedMultiCharacterCharLiteral(Exception):     @property


Question: 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: return ASTParenAttribute(id, arg)          return None<ins>    def _parse_paren_expression_list(self) -> ASTBaseParenExprList:        raise NotImplementedError</ins>


Question: 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)]

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


Question: 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__)()

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!


Question: from docutils import nodes from docutils.nodes import Element, Node, TextElement, system_message<ins>from docutils.parsers.rst import directives</ins>  from sphinx import addnodes from sphinx.addnodes import pending_xref

:noindex: prevents cross-referencing If a flag is to a directive, it can't be cross-referenced, and no permalink to it is generated. The following ReST: generates the following HTML: I would expect only to result in no index entry, not to prevent cross-referencing or permalinking. The HTML generated for the two class directives should be the same, i.e. the HTML for the Unindexed class should be OS: Linux Mint 19.1 (based on Ubuntu 18.04) Python version: 3.8.1 Sphinx version: 3.0.0 (HEAD) but also occurs with Sphinx 2.x, 1.x


Question: ]      option_spec = {        # have a dummy option to ensure proper errors on options,        # otherwise the option is taken as a continuation of the        # argument        'dummy': None        'noindexentry': directives.flag,     }      def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None:


Question: if name not in domain.objects:                 domain.objects[name] = (domain.env.docname, newestId, self.objtype)         indexText = self.get_index_text(name)        self.indexnode['entries'].append(('single', indexText, newestId, '', None))        if 'noindexentry' not in self.options:            indexText = self.get_index_text(name)            self.indexnode['entries'].append(('single', indexText, newestId, '', None))      @property     def object_type(self) -> str:diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py-- a/sphinx/domains/cpp.py++ b/sphinx/domains/cpp.py


Question: ]      option_spec = {<ins>        'noindexentry': directives.flag,</ins>         'tparam-line-spec': directives.flag,     }


Question: if decl.objectType == 'concept':                 isInConcept = True                 break        if not isInConcept:        if not isInConcept and 'noindexentry' not in self.options:             strippedName = name             for prefix in self.env.config.cpp_index_common_prefix:                 if name.startswith(prefix):diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py-- a/sphinx/domains/javascript.py++ b/sphinx/domains/javascript.py


Question: #: based on directive nesting     allow_nesting = False <ins>    option_spec = {        'noindex': directives.flag,        'noindexentry': directives.flag,    }</ins>     def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]:         """Breaks down construct signatures


Question: domain = cast(JavaScriptDomain, self.env.get_domain('js'))         domain.note_object(fullname, self.objtype, node_id, location=signode)         indextext = self.get_index_text(mod_name, name_obj)        if indextext:            self.indexnode['entries'].append(('single', indextext, node_id, '', None))        if 'noindexentry' not in self.options:            indextext = self.get_index_text(mod_name, name_obj)            if indextext:                self.indexnode['entries'].append(('single', indextext, node_id, '', None))      def get_index_text(self, objectname: str, name_obj: Tuple[str, str]) -> str:         name, obj = name_objdiff --git a/sphinx/domains/python.py b/sphinx/domains/python.py-- a/sphinx/domains/python.py++ b/sphinx/domains/python.py


Question: """     option_spec = {         'noindex': directives.flag,<ins>        'noindexentry': directives.flag,</ins>         'module': directives.unchanged,         'annotation': directives.unchanged,     }


Question: domain = cast(PythonDomain, self.env.get_domain('py'))         domain.note_object(fullname, self.objtype, node_id, location=signode)         indextext = self.get_index_text(modname, name_cls)        if indextext:            self.indexnode['entries'].append(('single', indextext, node_id, '', None))        if 'noindexentry' not in self.options:            indextext = self.get_index_text(modname, name_cls)            if indextext:                self.indexnode['entries'].append(('single', indextext, node_id, '', None))      def before_content(self) -> None:         """Handle object nesting before content


Question: 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]        if 'noindexentry' not in self.options:            modname = self.options.get('module', self.env.ref_context.get('py:module'))            node_id = signode['ids'][0]         name, cls = name_cls        if modname:            text = _('%s() (in module %s)') % (name, modname)            self.indexnode['entries'].append(('single', text, node_id, '', None))        else:            text = '%s; %s()' % (pairindextypes['builtin'], name)            self.indexnode['entries'].append(('pair', text, node_id, '', None))            name, cls = name_cls            if modname:                text = _('%s() (in module %s)') % (name, modname)                self.indexnode['entries'].append(('single', text, node_id, '', None))            else:                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.


Question: from sphinx import __display_version__ as __version__ from sphinx.application import Sphinx from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring<ins>from sphinx.util import inspect</ins>   class Config:

Decorated init doesn't show up in docs Subject: Decorated init won't be documented. I'm working on I have , so will be documented. But if I decorate the method, it will not show up in docs. I decorate it with , so the decorated object still has the same . I've found that the bug is due to this commit: I've printed the relevant variables in that function: And the root cause of the issue is in this line of code: Because now is not the method itself, but a decorated method, its does not contain the class anymore. This makes sphinx think it's not a method, i.e. . OS: <Unix/Linux/Mac/Win/other with version: ArchLinux Python version: 3.6 Sphinx version:1.6.5


Question: mod_path = cls_path.split('.')                         cls = functools.reduce(getattr, mod_path, mod)                     else:                        cls = obj.__globals__[cls_path]                        cls = inspect.unwrap(obj).__globals__[cls_path]                 except Exception:                     cls_is_owner = False                 else:


Question: def append_epilog(content: StringList, epilog: str) -> None:     """Append a string to content body as epilog."""     if epilog:        content.append('', '<generated>', 0)        if 0 < len(content):            source, lineno = content.info(-1)        else:            source = '<generated>'            lineno = 0        content.append('', source, lineno + 1)         for lineno, line in enumerate(epilog.splitlines()):             content.append(line, '<rst_epilog>', lineno)

Bad refs in pot files, when using rst_epilog To Reproduce produces with bad string numbers and "\<generated\" refs:


Question: ('deprecated', bool)])  def type_to_xref(text: str) -> addnodes.pending_xref:def type_to_xref(text: str, env: BuildEnvironment = None) -> addnodes.pending_xref:     """Convert a type string to a cross reference node."""     if text == 'None':         reftype = 'obj'     else:         reftype = 'class'     if env:        kwargs = {'py:module': env.ref_context.get('py:module'),                  'py:class': env.ref_context.get('py:class')}    else:        kwargs = {}     return pending_xref('', nodes.Text(text),                        refdomain='py', reftype=reftype, reftarget=text)                        refdomain='py', reftype=reftype, reftarget=text, **kwargs)  def _parse_annotation(annotation: str) -> List[Node]:def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Node]:     """Parse type annotation."""     def unparse(node: ast.AST) -> List[Node]:         if isinstance(node, ast.Attribute):

Regression: autodoc Dataclass variables reference target not found Describe the bug When I use and with my code which includes a dataclass with a variable of a custom type, I get a warning. To Reproduce Open the attached project . Install Sphinx. Run . Expected behavior I expect there to be no warning, or a clear message saying how I can avoid this warning. Your project Environment info macOS latest Python 3.7.7 Sphinx 3.1.2 (reproducible also with 3.1.0 but not 3.0.4)


Question: else:             raise SyntaxError  # unsupported syntax     if env is None:        warnings.warn("The env parameter for _parse_annotation becomes required now.",                      RemovedInSphinx50Warning, stacklevel=2)     try:         tree = ast_parse(annotation)         result = unparse(tree)         for i, node in enumerate(result):             if isinstance(node, nodes.Text):                result[i] = type_to_xref(str(node))                result[i] = type_to_xref(str(node), env)         return result     except SyntaxError:        return [type_to_xref(annotation)]        return [type_to_xref(annotation, env)]  def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist:def _parse_arglist(arglist: str, env: BuildEnvironment = None) -> addnodes.desc_parameterlist:     """Parse a list of arguments using AST parser"""     params = addnodes.desc_parameterlist(arglist)     sig = signature_from_str('(%s)' % arglist)


Question: node += addnodes.desc_sig_name('', param.name)          if param.annotation is not param.empty:            children = _parse_annotation(param.annotation)            children = _parse_annotation(param.annotation, env)             node += addnodes.desc_sig_punctuation('', ':')             node += nodes.Text(' ')             node += addnodes.desc_sig_name('', '', *children)  # type: ignore


Question: signode += addnodes.desc_name(name, name)         if arglist:             try:                signode += _parse_arglist(arglist)                signode += _parse_arglist(arglist, self.env)             except SyntaxError:                 # fallback to parse arglist original parser.                 # it supports to represent optional arguments (ex. "func(foo [, bar])")


Question: signode += addnodes.desc_parameterlist()          if retann:            children = _parse_annotation(retann)            children = _parse_annotation(retann, self.env)             signode += addnodes.desc_returns(retann, '', *children)          anno = self.options.get('annotation')


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


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


Question: # more information for mathjax secure url is here:     # https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn     app.add_config_value('mathjax_path',                         'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?'                         'config=TeX-AMS-MML_HTMLorMML', 'html')                         'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js',                         'html')     app.add_config_value('mathjax_options', {}, 'html')     app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')     app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')

Support mathjax 3.0 , and has a number of improvements - most notably on the speed of loading (something like an 80% decrease in load time). It would be great to get this into the Sphinx MathJax extension. The suggest that it will not be trivial to upgrade, but it may be worth it given the performance and modularity improvements. What do folks think?


Question: for subentry in indexentry[1].values():                 subentry[0].sort(key=keyfunc0)  # type: ignore         # sort the index entries; put all symbols at the front, even those        # following the letters in ASCII, this is where the chr(127) comes from        def keyfunc(entry: Tuple[str, List]) -> Tuple[str, str]:        # sort the index entries        def keyfunc(entry: Tuple[str, List]) -> Tuple[Tuple[int, str], str]:             key, (void, void, category_key) = entry             if category_key:                 # using specified category key to sort

Two sections called Symbols in index When using index entries with the following leading characters: £, and ← I get two sections called Symbols in the HTML output, the first containing all @ entries before ”normal” words and the second containing £ and ← entries after the ”normal” words. Both have the same anchor in HTML so the links at the top of the index page contain two Symbols links, one before the letters and one after, but both lead to the first section.


Question: lckey = unicodedata.normalize('NFD', key.lower())             if lckey.startswith('\N{RIGHT-TO-LEFT MARK}'):                 lckey = lckey[1:]             if lckey[0:1].isalpha() or lckey.startswith('_'):                lckey = chr(127) + lckey                # put non-symbol characters at the folloing group (1)                sortkey = (1, lckey)            else:                # put symbols at the front of the index (0)                sortkey = (0, lckey)             # ensure a determinstic order *within* letters by also sorting on             # the entry itself            return (lckey, entry[0])            return (sortkey, entry[0])         newlist = sorted(new.items(), key=keyfunc)          if group_entries:


Question: logger = logging.getLogger(__name__) <ins>uri_re = re.compile('[a-z]+://')</ins>  DEFAULT_REQUEST_HEADERS = {     'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',

linkcheck could also check local (internal) links Subject: linkcheck currently doesn't check local (internal) links, but this would be useful. <!-- Important: This is a list of issues for Sphinx, not a forum. If you'd like to post a question, please move to sphinx-users group. !forum/sphinx-users Thanks, --See above. Create a template project with sphinx-quickstart, put the following in Run Also a check for the local link. N/A OS: Arch Linux Python version: 3.6 Sphinx version: 1.7.6


Question: def check() -> Tuple[str, str, int]:             # check for various conditions without bothering the network            if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'ftp:')):            if len(uri) == 0 or uri.startswith(('#', 'mailto:')):                 return 'unchecked', '', 0             elif not uri.startswith(('http:', 'https:')):                return 'local', '', 0                if uri_re.match(uri):                    # non supported URI schemes (ex. ftp)                    return 'unchecked', '', 0                else:                    if path.exists(path.join(self.srcdir, uri)):                        return 'working', '', 0                    else:                        for rex in self.to_ignore:                            if rex.match(uri):                                return 'ignored', '', 0                        else:                            return 'broken', '', 0             elif uri in self.good:                 return 'working', 'old', 0             elif uri in self.broken:


Question: import builtins import inspect import re<ins>import sys</ins> import typing import warnings from inspect import Parameter

2 introduces WARNING: py:class reference target not found: Callable[[...], Awaitable[None]] Describe the bug My project, including the above function definition, builds cleanly with Sphinx 3.1.1 but with 3.1.2 I get the following warning. Note that the resulting parameter documentation does properly hyperlink and but does not get a link. https://qtrio-- To Reproduce Steps to reproduce the behavior: Expected behavior The error doesn't happen in either case and , , and all get properly hyperlinked. Your project Screenshots ! Environment info OS: Linux - Ubuntu 20.04 Python version: 3.8.3 Sphinx version: 3.1.2 Sphinx extensions: sphinxautodoctypehints sphinxqtdocumentation sphinxcontrib_trio Additional context


Question: return result         else:<ins>            if sys.version_info >= (3, 6):                if isinstance(node, ast.Constant):                    if node.value is Ellipsis:                        return [addnodes.desc_sig_punctuation('', "...")]                    else:                        return [nodes.Text(node.value)]            if sys.version_info < (3, 8):                if isinstance(node, ast.Ellipsis):                    return [addnodes.desc_sig_punctuation('', "...")]                elif isinstance(node, ast.NameConstant):                    return [nodes.Text(node.value)]</ins>             raise SyntaxError  # unsupported syntax      if env is None:


Question: dirname = path.dirname(d['root'])     if dirname and not dirname.endswith(path.sep):         dirname += path.sep    docpath = path.dirname(env.docname)    if docpath and not docpath.endswith(path.sep):        docpath += path.sep     d['path'] = dirname     d['basename'] = path.basename(d['root'])    d['docpath'] = docpath     d['language'] = env.config.language     try:         return filename_format.format(**d)

More customization options for figurelanguagefilename for localized images Is your feature request related to a problem? Please describe. I'm working on the localization of the , and we use a to hold the massive PO files that we use for Weblate and Sphinx. I'm now working on image localization () and I find that even though  seems to provide some customization option, it's impossible to host the localized images in the separate repository. Indeed, both the and substitution tokens resolve to absolute paths from the host system (e.g. ), and since I can't do post-processing of the subsituted string, I can't strip the base path to attempt using something like . Describe the solution you'd like I'd like the addition of one or more new path substitution tokens that can be used to customize the path to localized images more freely. For example, for this structure: and referencing , I could imagine two useful substitution tokens: Alternatively (and possible as a better solution), and could be changed to actually be relative to the Sphinx project's root folder, i.e. the in my example above, i.e.: (While the documentation currently states that these would be and , which is wrong in my tests on Linux with Sphinx 1.8.5). I don't specifically need access to the file-relative path in my use case, but I imagine that some projects may benefit from it. Describe alternatives you've considered I don't see any alternative option that would enable the workflow I want to use with localized images not being either in the original image's folder, or in one of its subfolders. Edit: We came up with ~two~ three hacks that we could use to workaround the currently limited substitution tokens offered by : Passing a class that redefines with our custom post-processing: Symlinking all localized images from the out-of-tree location to the in-tree location where Sphinx wants it: Overriding since apparently Python lets us do that, so we can do the post-processing we want: I did not test with latest Sphinx as it's not properly supported on ReadTheDocs yet, but the relevant code seems to be unchanged from 1.8.5: Additional context


Question: from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning from sphinx.environment import BuildEnvironment from sphinx.environment.adapters.toctree import TocTreefrom sphinx.ext.autodoc import Documenterfrom sphinx.ext.autodoc import Documenter, INSTANCEATTR from sphinx.ext.autodoc.directive import DocumenterBridge, Options from sphinx.ext.autodoc.importer import import_module from sphinx.ext.autodoc.mock import mock

Instance attributes are omitted with autosummary This issue is a followup of . Sorry, I forgot to open it. Is your feature request related to a problem? Please describe. Instance attributes are omitted when using the autosummary, as they cannot be imported. Consider the following class via will document the attribute, but via won't. Describe the solution you'd like Instance attributes should be documented, too Describe alternatives you've considered it did work before , i.e. for (although the documentation was omitted). Additional context files to reproduce the issue (including page build) Screenshot of !


Question: return nodes <ins>    def import_by_name(self, name: str, prefixes: List[str]) -> Tuple[str, Any, Any, str]:        with mock(self.config.autosummary_mock_imports):            try:                return import_by_name(name, prefixes)            except ImportError as exc:                # check existence of instance attribute                try:                    return import_ivar_by_name(name, prefixes)                except ImportError:                    pass                raise exc  # re-raise ImportError if instance attribute not found</ins>     def get_items(self, names: List[str]) -> List[Tuple[str, str, str, str]]:         """Try to import the given names, and return a list of         ``[(name, signature, summary_string, real_name), ...]``.


Question: display_name = name.split('.')[-1]              try:                with mock(self.config.autosummary_mock_imports):                    real_name, obj, parent, modname = import_by_name(name, prefixes=prefixes)                real_name, obj, parent, modname = self.import_by_name(name, prefixes=prefixes)             except ImportError:                 logger.warning(__('autosummary: failed to import %s'), name,                                location=self.get_source_info())


Question: raise ImportError(*e.args) from e  def import_ivar_by_name(name: str, prefixes: List[str] = [None]) -> Tuple[str, Any, Any, str]:    """Import an instance variable that has the given *name*, under one of the    *prefixes*.  The first name that succeeds is used.    """    try:        name, attr = name.rsplit(".", 1)        real_name, obj, parent, modname = import_by_name(name, prefixes)        qualname = real_name.replace(modname + ".", "")        analyzer = ModuleAnalyzer.for_module(modname)        if (qualname, attr) in analyzer.find_attr_docs():            return real_name + "." + attr, INSTANCEATTR, obj, modname    except (ImportError, ValueError):        pass    raise ImportError # -- :autolink: (smart default role) -------------------------------------------  def autolink_role(typ: str, rawtext: str, etext: str, lineno: int, inliner: Inliner,diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py-- a/sphinx/ext/autosummary/generate.py++ b/sphinx/ext/autosummary/generate.py


Question: from sphinx.config import Config from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning from sphinx.ext.autodoc import Documenterfrom sphinx.ext.autosummary import import_by_name, get_documenterfrom sphinx.ext.autosummary import import_by_name, import_ivar_by_name, get_documenter from sphinx.locale import __ from sphinx.pycode import ModuleAnalyzer, PycodeError from sphinx.registry import SphinxComponentRegistry


Question: name, obj, parent, modname = import_by_name(entry.name)             qualname = name.replace(modname + ".", "")         except ImportError as e:            _warn(__('[autosummary] failed to import %r: %s') % (entry.name, e))            continue            try:                # try to importl as an instance attribute                name, obj, parent, modname = import_ivar_by_name(entry.name)                qualname = name.replace(modname + ".", "")            except ImportError:                _warn(__('[autosummary] failed to import %r: %s') % (entry.name, e))                continue          context = {}         if app:


Question: def merge_special_members_option(options: Dict) -> None:     """Merge :special-members: option to :members: option."""<ins>    warnings.warn("merge_special_members_option() is deprecated.",                  RemovedInSphinx50Warning, stacklevel=2)</ins>     if 'special-members' in options and options['special-members'] is not ALL:         if options.get('members') is ALL:             pass

Support defining specific for autodoc Is your feature request related to a problem? Please describe. Currently, if I'm using autodoc, the option does not allow specification of which private members to document. The current behavior is to document all private members, but what if I would only like to document 1 or 2? Describe the solution you'd like For to take arguments, similarly to how currently works Describe alternatives you've considered The current best way to do this is to explicitly list each class in a module and use Some prior discussion:


Question: options['members'] = options['special-members']  <ins>def merge_members_option(options: Dict) -> None:    """Merge :*-members: option to the :members: option."""    if options.get('members') is ALL:        # merging is not needed when members: ALL        return    members = options.setdefault('members', [])    for key in {'private-members', 'special-members'}:        if key in options and options[key] is not ALL:            for member in options[key]:                if member not in members:                    members.append(member)</ins> # Some useful event listener factories for autodoc-process-docstring.  def cut_lines(pre: int, post: int = 0, what: str = None) -> Callable:


Question: keep = has_doc or self.options.undoc_members             elif (namespace, membername) in attr_docs:                 if want_all and isprivate:                    # ignore members whose name starts with _ by default                    keep = self.options.private_members                    if self.options.private_members is None:                        keep = False                    elif self.options.private_members is ALL:                        keep = True                    else:                        keep = membername in self.options.private_members                 else:                     # keep documented attributes                     keep = True                 isattr = True             elif want_all and isprivate:                # ignore members whose name starts with _ by default                keep = self.options.private_members and \                    (has_doc or self.options.undoc_members)                if has_doc or self.options.undoc_members:                    if self.options.private_members is None:                        keep = False                    elif self.options.private_members is ALL:                        keep = True                    elif is_filtered_inherited_member(membername):                        keep = False                    else:                        keep = membername in self.options.private_members                else:                    keep = False             else:                 if self.options.members is ALL and is_filtered_inherited_member(membername):                     keep = False


Question: 'show-inheritance': bool_option, 'synopsis': identity,         'platform': identity, 'deprecated': bool_option,         'member-order': member_order_option, 'exclude-members': members_set_option,        'private-members': bool_option, 'special-members': members_option,        'private-members': members_option, 'special-members': members_option,         'imported-members': bool_option, 'ignore-module-all': bool_option     }  # type: Dict[str, Callable]      def __init__(self, *args: Any) -> None:         super().__init__(*args)        merge_special_members_option(self.options)        merge_members_option(self.options)         self.__all__ = None      @classmethod


Question: 'noindex': bool_option, 'inherited-members': inherited_members_option,         'show-inheritance': bool_option, 'member-order': member_order_option,         'exclude-members': members_set_option,        'private-members': bool_option, 'special-members': members_option,        'private-members': members_option, 'special-members': members_option,     }  # type: Dict[str, Callable]      _signature_class = None  # type: Any


Question: def __init__(self, *args: Any) -> None:         super().__init__(*args)        merge_special_members_option(self.options)        merge_members_option(self.options)      @classmethod     def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any


Question: # ==========================================================================     def _parse_template_parameter_list(self) -> ASTTemplateParams:        # only: '<' parameter-list '>'        # we assume that 'template' has just been parsed        templateParams = []  # type: List[ASTTemplateParam]        self.skip_ws()        if not self.skip_string("<"):            self.fail("Expected '<' after 'template'")        prevErrors = []        while 1:            self.skip_ws()            if self.skip_word('template'):                # declare a tenplate template parameter                nestedParams = self._parse_template_parameter_list()            else:                nestedParams = None            self.skip_ws()    def _parse_template_paramter(self) -> ASTTemplateParam:        if self.skip_word('template'):            # declare a tenplate template parameter            nestedParams = self._parse_template_parameter_list()        else:            nestedParams = None        pos = self.pos        try:            # Unconstrained type parameter or template type parameter             key = None            self.skip_ws()             if self.skip_word_and_ws('typename'):                 key = 'typename'             elif self.skip_word_and_ws('class'):

Error in template parameter list. Describe the bug I appear to have some valid C++14 syntax which causes Sphinx's C++ parser to choke. Here is the full error trace: To Reproduce Steps to reproduce the behavior: Expected behavior Build should succeed


Question: elif nestedParams:                 self.fail("Expected 'typename' or 'class' after "                           "template template parameter list.")            if key:                # declare a type or template type parameter                self.skip_ws()                parameterPack = self.skip_string('...')                self.skip_ws()                if self.match(identifier_re):                    identifier = ASTIdentifier(self.matched_text)                else:                    identifier = None                self.skip_ws()                if not parameterPack and self.skip_string('='):                    default = self._parse_type(named=False, outer=None)                else:                    default = None                data = ASTTemplateKeyParamPackIdDefault(key, identifier,                                                        parameterPack, default)                if nestedParams:                    # template type                    templateParams.append(                        ASTTemplateParamTemplateType(nestedParams, data))                else:                    # type                    templateParams.append(ASTTemplateParamType(data))             else:                # declare a non-type parameter, or constrained type parameter                pos = self.pos                try:                    param = self._parse_type_with_init('maybe', 'templateParam')                    templateParams.append(ASTTemplateParamNonType(param))                except DefinitionError as e:                    msg = "If non-type template parameter or constrained template parameter"                    prevErrors.append((e, msg))                    self.pos = pos                self.fail("Expected 'typename' or 'class' in tbe "                          "beginning of template type parameter.")            self.skip_ws()            parameterPack = self.skip_string('...')            self.skip_ws()            if self.match(identifier_re):                identifier = ASTIdentifier(self.matched_text)            else:                identifier = None            self.skip_ws()            if not parameterPack and self.skip_string('='):                default = self._parse_type(named=False, outer=None)            else:                default = None                if self.current_char not in ',>':                    self.fail('Expected "," or ">" after (template) type parameter.')            data = ASTTemplateKeyParamPackIdDefault(key, identifier,                                                    parameterPack, default)            if nestedParams:                return ASTTemplateParamTemplateType(nestedParams, data)            else:                return ASTTemplateParamType(data)        except DefinitionError as eType:            if nestedParams:                raise            try:                # non-type parameter or constrained type parameter                self.pos = pos                param = self._parse_type_with_init('maybe', 'templateParam')                return ASTTemplateParamNonType(param)            except DefinitionError as eNonType:                self.pos = pos                header = "Error when parsing template parameter."                errs = []                errs.append(                    (eType, "If unconstrained type parameter or template type parameter"))                errs.append(                    (eNonType, "If constrained type parameter or non-type parameter"))                raise self._make_multi_error(errs, header)    def _parse_template_parameter_list(self) -> ASTTemplateParams:        # only: '<' parameter-list '>'        # we assume that 'template' has just been parsed        templateParams = []  # type: List[ASTTemplateParam]        self.skip_ws()        if not self.skip_string("<"):            self.fail("Expected '<' after 'template'")        while 1:            pos = self.pos            err = None            try:                param = self._parse_template_paramter()                templateParams.append(param)            except DefinitionError as eParam:                self.pos = pos                err = eParam             self.skip_ws()             if self.skip_string('>'):                 return ASTTemplateParams(templateParams)             elif self.skip_string(','):                prevErrors = []                 continue             else:                 header = "Error in template parameter list."                errs = []                if err:                    errs.append((err, "If parameter"))                 try:                    self.fail('Expected "=", ",", or ">".')                    self.fail('Expected "," or ">".')                 except DefinitionError as e:                    prevErrors.append((e, ""))                raise self._make_multi_error(prevErrors, header)                    errs.append((e, "If no parameter"))                print(errs)                raise self._make_multi_error(errs, header)      def _parse_template_introduction(self) -> ASTTemplateIntroduction:         pos = self.pos


Question: _descs = self.__class__(_descs, self._config).lines()         return _name, _type, _descs     def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False                        ) -> List[Tuple[str, str, List[str]]]:    def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False,                        multiple: bool = False) -> List[Tuple[str, str, List[str]]]:         self._consume_empty()         fields = []         while not self._is_section_break():             _name, _type, _desc = self._consume_field(parse_type, prefer_type)            if _name or _type or _desc:            if multiple and _name:                for name in _name.split(","):                    fields.append((name.strip(), _type, _desc))            elif _name or _type or _desc:                 fields.append((_name, _type, _desc,))         return fields

Render error when combining multiple input parameters in docstring Describe the bug & Reproduce My team is writing a function in Python, which contains 3 inputs that are similar, so we want to put them in the same line in the docstring. As described in 4. Parameters in , this is possible if you write something like this: However, this produces: <img width="406" alt="" src="https://user-"Even worse, when "optional", the rendered HTML stays the same as the screenshot above, so there is no way to tell whether it is optional: Expected behavior Something like x1, x2 (arraylike, optional_) - Input arrays, description of x1, x2. Environment info OS: macOS 10.15.5 (19F101) Python version: 3.7.7 Sphinx version: 3.0.3. Extra tools: browser: Firefox 79.0a1 or Safari 13.1.1 Sphinx extensions:


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


Question: def setup(app: Sphinx) -> Dict[str, Any]:     app.add_builder(MessageCatalogBuilder)     app.add_config_value('gettext_compact', True, 'gettext')    app.add_config_value('gettext_compact', True, 'gettext', Any)     app.add_config_value('gettext_location', True, 'gettext')     app.add_config_value('gettext_uuid', False, 'gettext')     app.add_config_value('gettext_auto_build', True, 'env')diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py-- a/sphinx/util/i18n.py++ b/sphinx/util/i18n.py

Allow more compaction in gettext builder The OKFN people manually merge all generated message catalogs into a single file for upload. {{{gettext_compact}}} should support that use case too. Bitbucket: Originally reported by: Robert Lehmann Originally created at: 2011-10-11T16:43:20.007


Question: from collections import namedtuple from datetime import datetime, timezone from os import pathfrom typing import Callable, Generator, List, Set, Tuplefrom typing import Callable, Generator, List, Set, Tuple, Union  import babel.dates from babel.messages.mofile import write_mo


Question: return ret  def docname_to_domain(docname: str, compation: bool) -> str:def docname_to_domain(docname: str, compation: Union[bool, str]) -> str:     """Convert docname to domain for catalogs."""    if isinstance(compation, str):        return compation     if compation:         return docname.split(SEP, 1)[0]     else:


Question: dangling_warnings = {         'term': 'term not in glossary: %(target)s',<del>        'ref':  'undefined label: %(target)s (if the link has no caption '                'the label must precede a section header)',</del>         'numref':  'undefined label: %(target)s',         'keyword': 'unknown keyword: %(target)s',         'doc': 'unknown document: %(target)s',

References to figures without captions: errors in both HTML and LaTeX Describe the bug Using figures without captions causes errors in both HTML (though these are properly reported when source is processed) and in LaTeX (they are not reported until LaTeX says there were undefined references). This was the test document, compiled with sphinx 2.2.2 from pypi; was to , the project was otherwise generated with sphinx-build with no other changes. It is attached here: and these are the results: warning: WARNING: undefined label: fig-sample-nocaption (if the link has no caption the label must precede a section header) is HTML output (the error highlighted corresponds to the warning mentioned above): ! is LaTeX (pdflatex) output: ! Expected behavior I expect to produce valid LaTeX input without undefined references; figures to be referencable in LaTeX (this could be an optional setting perhaps causing uncaptioned figured to produce only "Figure 4.1." caption); about figure not being captioned to be more meaningful -- I understand that non-numbered figure cannot be referenced via :ref: (as the label will not resolve to any text) but the warning is not pointing to how to fix the issue. Environment info OS: Ubuntu 18.04 LTS Python version: 3.6.8 Sphinx version: 2.2.2 Sphinx extensions: none Extra tools: pdflatex TeXLive


Question: RemovedInSphinx40Warning, stacklevel=2)  def warn_missing_reference(app: "Sphinx", domain: Domain, node: pending_xref) -> bool:    if domain.name != 'std' or node['reftype'] != 'ref':        return None    else:        target = node['reftarget']        if target not in domain.anonlabels:  # type: ignore            msg = __('undefined label: %s')        else:            msg = __('Failed to create a cross reference. A title or caption not found: %s')        logger.warning(msg % target, location=node, type='ref', subtype=node['reftype'])        return True def setup(app: "Sphinx") -> Dict[str, Any]:     app.add_domain(StandardDomain)    app.connect('warn-missing-reference', warn_missing_reference)      return {         'version': 'builtin',diff --git a/sphinx/events.py b/sphinx/events.py-- a/sphinx/events.py++ b/sphinx/events.py


Question: 'doctree-read': 'the doctree before being pickled',     'env-merge-info': 'env, read docnames, other env instance',     'missing-reference': 'env, node, contnode',    'warn-missing-reference': 'domain, node',     'doctree-resolved': 'doctree, docname',     'env-updated': 'env',     'html-collect-pages': 'builder',diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py-- a/sphinx/transforms/post_transforms/__init__.py++ b/sphinx/transforms/post_transforms/__init__.py


Question: warn = False         if not warn:             return        if domain and typ in domain.dangling_warnings:        if self.app.emit_firstresult('warn-missing-reference', domain, node):            return        elif domain and typ in domain.dangling_warnings:             msg = domain.dangling_warnings[typ]         elif node.get('refdomain', 'std') not in ('', 'std'):             msg = (__('%s:%s reference target not found: %%(target)s') %


Question: napoleon_use_param = True         napoleon_use_rtype = True         napoleon_use_keyword = True<ins>        napoleon_preprocess_types = False</ins>         napoleon_type_aliases = None         napoleon_custom_sections = None

Warning: Inline literal start-string without end-string in Numpy style Parameters section Describe the bug The following docstring generates a warning on the line of the timeout parameter. Removing the quote around cause the warning to go away. To Reproduce Steps to reproduce the behavior: Expected behavior I do not expect to see a warning there and was not seeing any before 3.2 Your project The project is build under the Documentation build action. Environment info OS: Mac Os and Linux Python version: 3.8.2 and 3.8.5 Sphinx version: 3.2.0 Sphinx extensions: "", "","", "", "", "", ""


Question: :returns: *bool* -- True if successful, False otherwise     napoleon_preprocess_types : :obj:`bool` (Defaults to False)        Enable the type preprocessor for numpy style docstrings.     napoleon_type_aliases : :obj:`dict` (Defaults to None)         Add a mapping of strings to string, translating types in numpy        style docstrings.        style docstrings. Only works if ``napoleon_preprocess_types = True``.      napoleon_custom_sections : :obj:`list` (Defaults to None)         Add a list of custom sections to include, expanding the list of parsed sections.


Question: 'napoleon_use_param': (True, 'env'),         'napoleon_use_rtype': (True, 'env'),         'napoleon_use_keyword': (True, 'env'),        'napoleon_preprocess_types': (False, 'env'),         'napoleon_type_aliases': (None, 'env'),         'napoleon_custom_sections': (None, 'env')     }diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py-- a/sphinx/ext/napoleon/docstring.py++ b/sphinx/ext/napoleon/docstring.py


Question: _name, _type = line, ''         _name, _type = _name.strip(), _type.strip()         _name = self._escape_args_and_kwargs(_name)        _type = _convert_numpy_type_spec(            _type,            location=self._get_location(),            translations=self._config.napoleon_type_aliases or {},        )        if self._config.napoleon_preprocess_types:            _type = _convert_numpy_type_spec(                _type,                location=self._get_location(),                translations=self._config.napoleon_type_aliases or {},            )          if prefer_type and not _type:             _type, _name = _name, _type


Question: from collections import deque from io import StringIO from os import pathfrom typing import Any, Callable, Dict, IO, List, Tuple, Unionfrom typing import Any, Callable, Dict, IO, List, Optional, Tuple, Union  from docutils import nodes from docutils.nodes import Element, TextElement

locale/ translation ignored Describe the bug I read [1] as it should be possible to add a file ) and through that change translations or add additional translation to <language. When I add. [1] [2] To Reproduce Steps to reproduce the behavior: Notice that . Expected behavior The caption label for the figure (again for the sake of testing). Your project Screenshots ! Environment info OS: Arch Linux Python version: 3.7.3 Sphinx version: 2.1.2 Sphinx extensions: none Extra tools: none


Question: if catalog.domain == 'sphinx' and catalog.is_outdated():                     catalog.write_mo(self.config.language)             locale_dirs = [None, path.join(package_dir, 'locale')] + list(repo.locale_dirs)            locale_dirs = [None]  # type: List[Optional[str]]            locale_dirs += list(repo.locale_dirs)            locale_dirs += [path.join(package_dir, 'locale')]             self.translator, has_translation = locale.init(locale_dirs, self.config.language)             if has_translation or self.config.language == 'en':                 # "en" never needs to be translateddiff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py-- a/sphinx/locale/__init__.py++ b/sphinx/locale/__init__.py


Question: translators = defaultdict(NullTranslations)  # type: Dict[Tuple[str, str], NullTranslations]  def init(locale_dirs: List[str], language: str,def init(locale_dirs: List[Optional[str]], language: str,          catalog: str = 'sphinx', namespace: str = 'general') -> Tuple[NullTranslations, bool]:     """Look for message catalogs in `locale_dirs` and *ensure* that there is at     least a NullTranslations catalog set in `translators`. If called multiple


Question: return None  <ins>class ObjectMember(tuple):    """A member of object.    This is used for the result of `Documenter.get_object_members()` to    represent each member of the object.    .. Note::       An instance of this class behaves as a tuple of (name, object)       for compatibility to old Sphinx.  The behavior will be dropped       in the future.  Therefore extensions should not use the tuple       interface.    """    def __new__(cls, name: str, obj: Any, **kwargs: Any) -> Any:        return super().__new__(cls, (name, obj))  # type: ignore    def __init__(self, name: str, obj: Any, skipped: bool = False) -> None:        self.__name__ = name        self.object = obj        self.skipped = skippedObjectMembers = Union[List[ObjectMember], List[Tuple[str, Any]]]</ins> class Documenter:     """     A Documenter knows how to autodocument a single object type.  When

All identifiers should be passed to autodoc-skip-member, even if not in all Is your feature request related to a problem? Please describe. I have a Python project for which I've generated docs. It did well. Almost everything was doc'ed. I knew about the default of excluding anything starting with '_' so I created an autodoc-skip-member function that would include those. It works. I see a bunch of private methods and functions included. But...I have a module, let's call it XYZ that has both private and public functions. Sphinx is only doc'ing the public functions of XYZ, but not its private functions. I have other modules that have private functions, and it's doc'ing those .I a print() to the autodoc-skip-member function and it doesn't even print out the of those private functions so it seems it's not even seeing it. I figured it out. The module had certain identifiers listed in , and was not passing anything else in that module to autodoc-skip-member. Describe the solution you'd like Sphinx should pass through all members, not just the ones in . Maybe add something to the object that is passed to autodoc-skip-members that indicates it would have been excluded by the designator, or some such. Describe alternatives you've considered I simply removed the from the file.


Question: for line, src in zip(more_content.data, more_content.items):                 self.add_line(line, src[0], src[1])     def get_object_members(self, want_all: bool) -> Tuple[bool, List[Tuple[str, Any]]]:    def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]:         """Return `(members_check_module, members)` where `members` is a         list of `(membername, member)` pairs of the members of *self.object*.


Question: members = get_object_members(self.object, self.objpath, self.get_attr, self.analyzer)         if not want_all:             if not self.options.members:                return False, []                return False, []  # type: ignore             # specific members given             selected = []            for name in self.options.members:            for name in self.options.members:  # type: str                 if name in members:                     selected.append((name, members[name].value))                 else:


Question: return False, [(m.name, m.value) for m in members.values()                            if m.directly_defined]     def filter_members(self, members: List[Tuple[str, Any]], want_all: bool    def filter_members(self, members: ObjectMembers, want_all: bool                        ) -> List[Tuple[str, Any, bool]]:         """Filter the given member list.


Question: attr_docs = {}          # process members and determine which to skip        for (membername, member) in members:        for obj in members:            membername, member = obj             # if isattr is True, the member is documented as an attribute             if member is INSTANCEATTR:                 isattr = True


Question: # ignore undocumented members if :undoc-members: is not given                     keep = has_doc or self.options.undoc_members <ins>            if isinstance(obj, ObjectMember) and obj.skipped:                # forcedly skipped member (ex. a module attribute not defined in __all__)                keep = False</ins>             # give the user a chance to decide whether this member             # should be skipped             if self.env.app:


Question: if self.options.deprecated:             self.add_line('   :deprecated:', sourcename)     def get_object_members(self, want_all: bool) -> Tuple[bool, List[Tuple[str, Any]]]:    def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]:         if want_all:            if self.__all__:                memberlist = self.__all__            else:            members = get_module_members(self.object)            if not self.__all__:                 # for implicit module members, check __module__ to avoid                 # documenting imported objects                return True, get_module_members(self.object)                return True, members            else:                ret = []                for name, value in members:                    if name in self.__all__:                        ret.append(ObjectMember(name, value))                    else:                        ret.append(ObjectMember(name, value, skipped=True))                return False, ret         else:             memberlist = self.options.members or []        ret = []        for mname in memberlist:            try:                ret.append((mname, safe_getattr(self.object, mname)))            except AttributeError:                logger.warning(                    __('missing attribute mentioned in :members: or __all__: '                       'module %s, attribute %s') %                    (safe_getattr(self.object, '__name__', '???'), mname),                    type='autodoc'                )        return False, ret            ret = []            for name in memberlist:                try:                    value = safe_getattr(self.object, name)                    ret.append(ObjectMember(name, value))                except AttributeError:                    logger.warning(__('missing attribute mentioned in :members: option: '                                      'module %s, attribute %s') %                                   (safe_getattr(self.object, '__name__', '???'), name),                                   type='autodoc')            return False, ret      def sort_members(self, documenters: List[Tuple["Documenter", bool]],                      order: str) -> List[Tuple["Documenter", bool]]: