Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn on deprecated Python-specific index types #11412

Merged
merged 10 commits into from May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES
Expand Up @@ -14,6 +14,11 @@ Incompatible changes
Deprecated
----------

* #11412: Emit warnings on using a deprecated Python-specific index entry type
(namely, ``module``, ``keyword``, ``operator``, ``object``, ``exception``,
``statement``, and ``builtin``) in the :rst:dir:`index` directive, and
set the removal version to Sphinx 9. Patch by Adam Turner.

Features added
--------------

Expand Down
5 changes: 5 additions & 0 deletions doc/usage/configuration.rst
Expand Up @@ -337,6 +337,7 @@ General configuration
* ``epub.unknown_project_files``
* ``epub.duplicated_toc_entry``
* ``i18n.inconsistent_references``
* ``index``
* ``image.not_readable``
* ``ref.term``
* ``ref.ref``
Expand Down Expand Up @@ -388,6 +389,10 @@ General configuration

Added ``i18n.inconsistent_references``

.. versionadded:: 7.1

Added ``index`` warning type.

.. confval:: needs_sphinx

If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will
Expand Down
71 changes: 55 additions & 16 deletions doc/usage/restructuredtext/directives.rst
Expand Up @@ -896,9 +896,10 @@ mainly contained in information units, such as the language reference.

.. index::
single: execution; context
module: __main__
module: sys
pair: module; __main__
pair: module; sys
triple: module; search; path
seealso: scope

The execution context
---------------------
Expand All @@ -916,25 +917,63 @@ mainly contained in information units, such as the language reference.
The possible entry types are:

single
Creates a single index entry. Can be made a subentry by separating the
subentry text with a semicolon (this notation is also used below to
describe what entries are created).
Creates a single index entry.
Can be made a sub-entry by separating the sub-entry text with a semicolon
(this notation is also used below to describe what entries are created).
Examples:

.. code:: reStructuredText

.. index:: single: execution
single: execution; context

- ``single: execution`` creates an index entry labelled ``execution``.
- ``single: execution; context`` creates an sub-entry of ``execution``
labelled ``context``.
pair
``pair: loop; statement`` is a shortcut that creates two index entries,
namely ``loop; statement`` and ``statement; loop``.
A shortcut to create two index entries.
The pair of values must be separated by a semicolon.
Example:

.. code:: reStructuredText

.. index:: pair: loop; statement

This would create two index entries; ``loop; statement`` and ``statement; loop``.
triple
Likewise, ``triple: module; search; path`` is a shortcut that creates
three index entries, which are ``module; search path``, ``search; path,
module`` and ``path; module search``.
A shortcut to create three index entries.
All three values must be separated by a semicolon.
Example:

.. code:: reStructuredText

.. index:: triple: module; search; path

This would create three index entries; ``module; search path``,
``search; path, module``, and ``path; module search``.
see
``see: entry; other`` creates an index entry that refers from ``entry`` to
``other``.
A shortcut to create an index entry that refers to another entry.
Example:

.. code:: reStructuredText

.. index:: see: entry; other

This would create an index entry referring from ``entry`` to ``other``
(i.e. 'entry': See 'other').
seealso
Like ``see``, but inserts "see also" instead of "see".
Like ``see``, but inserts 'see also' instead of 'see'.
module, keyword, operator, object, exception, statement, builtin
These all create two index entries. For example, ``module: hashlib``
creates the entries ``module; hashlib`` and ``hashlib; module``. (These
are Python-specific and therefore deprecated.)
These **deprecated** shortcuts all create two index entries.
For example, ``module: hashlib`` creates the entries ``module; hashlib``
and ``hashlib; module``.

.. deprecated:: 1.0
These Python-specific entry types are deprecated.

.. versionchanged:: 7.1
Removal version set to Sphinx 9.0.
Using these entry types will now emit warnings with the ``index`` category.

You can mark up "main" index entries by prefixing them with an exclamation
mark. The references to "main" entries are emphasized in the generated
Expand Down
5 changes: 0 additions & 5 deletions sphinx/builders/gettext.py
Expand Up @@ -16,7 +16,6 @@
from sphinx import addnodes, package_dir
from sphinx.application import Sphinx
from sphinx.builders import Builder
from sphinx.domains.python import pairindextypes
from sphinx.errors import ThemeError
from sphinx.locale import __
from sphinx.util import logging, split_index_msg
Expand Down Expand Up @@ -159,10 +158,6 @@ def write_doc(self, docname: str, doctree: nodes.document) -> None:
for node, entries in traverse_translatable_index(doctree):
for typ, msg, _tid, _main, _key in entries:
for m in split_index_msg(typ, msg):
if typ == 'pair' and m in pairindextypes.values():
# avoid built-in translated message was incorporated
# in 'sphinx.util.nodes.process_index_entry'
continue
catalog.add(m, node)


Expand Down
18 changes: 9 additions & 9 deletions sphinx/domains/python.py
Expand Up @@ -50,13 +50,13 @@


pairindextypes = {
'module': _('module'),
'keyword': _('keyword'),
'operator': _('operator'),
'object': _('object'),
'exception': _('exception'),
'statement': _('statement'),
'builtin': _('built-in function'),
'module': 'module',
'keyword': 'keyword',
'operator': 'operator',
'object': 'object',
'exception': 'exception',
'statement': 'statement',
'builtin': 'built-in function',
}


Expand Down Expand Up @@ -729,7 +729,7 @@ def add_target_and_index(self, name_cls: tuple[str, str], sig: str,
text = _('%s() (in module %s)') % (name, modname)
self.indexnode['entries'].append(('single', text, node_id, '', None))
else:
text = f'{pairindextypes["builtin"]}; {name}()'
text = f'built-in function; {name}()'
self.indexnode['entries'].append(('pair', text, node_id, '', None))

def get_index_text(self, modname: str, name_cls: tuple[str, str]) -> str | None:
Expand Down Expand Up @@ -1058,7 +1058,7 @@ def run(self) -> list[Node]:
# the platform and synopsis aren't printed; in fact, they are only
# used in the modindex currently
ret.append(target)
indextext = f'{pairindextypes["module"]}; {modname}'
indextext = f'module; {modname}'
inode = addnodes.index(entries=[('pair', indextext, node_id, '', None)])
ret.append(inode)
ret.extend(content_node.children)
Expand Down
6 changes: 0 additions & 6 deletions sphinx/locale/__init__.py
Expand Up @@ -223,9 +223,3 @@ def gettext(message: str) -> str:
'tip': _('Tip'),
'warning': _('Warning'),
}

# Moved to sphinx.directives.other (will be overridden later)
versionlabels: dict[str, str] = {}

# Moved to sphinx.domains.python (will be overridden later)
pairindextypes: dict[str, str] = {}
24 changes: 14 additions & 10 deletions sphinx/util/nodes.py
Expand Up @@ -365,19 +365,23 @@ def process_index_entry(entry: str, targetid: str,
if entry.startswith('!'):
main = 'main'
entry = entry[1:].lstrip()
for type in pairindextypes:
if entry.startswith(type + ':'):
value = entry[len(type) + 1:].strip()
value = pairindextypes[type] + '; ' + value
for index_type in pairindextypes:
if entry.startswith(f'{index_type}:'):
value = entry[len(index_type) + 1:].strip()
value = f'{pairindextypes[index_type]}; {value}'
# xref RemovedInSphinx90Warning
logger.warning(__('%r is deprecated for index entries (from entry %r). '
"Use 'pair: %s' instead."),
index_type, entry, value, type='index')
indexentries.append(('pair', value, targetid, main, None))
break
else:
for type in indextypes:
if entry.startswith(type + ':'):
value = entry[len(type) + 1:].strip()
if type == 'double':
type = 'pair'
indexentries.append((type, value, targetid, main, None))
for index_type in indextypes:
if entry.startswith(f'{index_type}:'):
value = entry[len(index_type) + 1:].strip()
if index_type == 'double':
index_type = 'pair'
indexentries.append((index_type, value, targetid, main, None))
break
# shorthand notation for single entries
else:
Expand Down
7 changes: 0 additions & 7 deletions tests/roots/test-intl/index_entries.txt
Expand Up @@ -20,12 +20,5 @@ various index entries
triple: First; Second; Third
see: Entry; Mailing List
seealso: See; Newsletter
module: Module
keyword: Keyword
operator: Operator
object: Object
exception: Exception
statement: Statement
builtin: Builtin

That's all.
1 change: 0 additions & 1 deletion tests/roots/test-root/markup.txt
Expand Up @@ -373,7 +373,6 @@ Index markup
pair: entry; pair
double: entry; double
triple: index; entry; triple
keyword: with
see: from; to
seealso: fromalso; toalso

Expand Down
2 changes: 1 addition & 1 deletion tests/roots/test-warnings/index.rst
Expand Up @@ -27,7 +27,7 @@ Don't download :download:`this <nonexisting.png>`.
.. index::
single:
pair:
keyword:
seealso:

.. Invalid code-block
.. code-block:: c
Expand Down
7 changes: 0 additions & 7 deletions tests/test_build_gettext.py
Expand Up @@ -117,13 +117,6 @@ def msgid_getter(msgid):
"Third",
"Entry",
"See",
"Module",
"Keyword",
"Operator",
"Object",
"Exception",
"Statement",
"Builtin",
]
for expect in expected_msgids:
assert expect in msgids
Expand Down
2 changes: 1 addition & 1 deletion tests/test_environment_indexentries.py
@@ -1,4 +1,4 @@
"""Test the sphinx.environment.managers.indexentries."""
"""Test the sphinx.environment.adapters.indexentries."""

import pytest

Expand Down
2 changes: 1 addition & 1 deletion tests/test_environment_toctree.py
@@ -1,4 +1,4 @@
"""Test the sphinx.environment.managers.toctree."""
"""Test the sphinx.environment.adapters.toctree."""

import pytest
from docutils import nodes
Expand Down
7 changes: 0 additions & 7 deletions tests/test_intl.py
Expand Up @@ -727,13 +727,6 @@ def wrap_nest(parenttag, childtag, keyword):
wrap('a', 'THIRD, FIRST'),
wrap_nest('li', 'ul', 'ENTRY'),
wrap_nest('li', 'ul', 'SEE'),
wrap('a', 'MODULE'),
wrap('a', 'KEYWORD'),
wrap('a', 'OPERATOR'),
wrap('a', 'OBJECT'),
wrap('a', 'EXCEPTION'),
wrap('a', 'STATEMENT'),
wrap('a', 'BUILTIN'),
]
for expr in expected_exprs:
assert_re_search(expr, result, re.M)
Expand Down