File fix-sphinx-72.patch of Package python310

---
 Doc/c-api/bytearray.rst               |    2 
 Doc/c-api/bytes.rst                   |    2 
 Doc/c-api/capsule.rst                 |    2 
 Doc/c-api/complex.rst                 |    2 
 Doc/c-api/concrete.rst                |    6 -
 Doc/c-api/dict.rst                    |    4 
 Doc/c-api/exceptions.rst              |    6 -
 Doc/c-api/file.rst                    |    2 
 Doc/c-api/float.rst                   |    2 
 Doc/c-api/function.rst                |    2 
 Doc/c-api/import.rst                  |    4 
 Doc/c-api/init.rst                    |   14 +--
 Doc/c-api/intro.rst                   |    8 -
 Doc/c-api/list.rst                    |    6 -
 Doc/c-api/long.rst                    |    4 
 Doc/c-api/mapping.rst                 |    2 
 Doc/c-api/memoryview.rst              |    2 
 Doc/c-api/method.rst                  |    4 
 Doc/c-api/module.rst                  |    2 
 Doc/c-api/none.rst                    |    2 
 Doc/c-api/number.rst                  |   12 +-
 Doc/c-api/object.rst                  |   12 +-
 Doc/c-api/sequence.rst                |    4 
 Doc/c-api/set.rst                     |    6 -
 Doc/c-api/structures.rst              |    4 
 Doc/c-api/tuple.rst                   |    2 
 Doc/c-api/type.rst                    |    2 
 Doc/c-api/typeobj.rst                 |    4 
 Doc/conf.py                           |    5 +
 Doc/extending/newtypes.rst            |    2 
 Doc/library/_thread.rst               |    2 
 Doc/library/binascii.rst              |    6 -
 Doc/library/cmath.rst                 |    2 
 Doc/library/copy.rst                  |    2 
 Doc/library/copyreg.rst               |    4 
 Doc/library/dis.rst                   |    2 
 Doc/library/exceptions.rst            |   10 +-
 Doc/library/fnmatch.rst               |    4 
 Doc/library/functions.rst             |   10 +-
 Doc/library/http.client.rst           |    2 
 Doc/library/imp.rst                   |    2 
 Doc/library/internet.rst              |    2 
 Doc/library/locale.rst                |    4 
 Doc/library/marshal.rst               |    4 
 Doc/library/os.path.rst               |    2 
 Doc/library/os.rst                    |    4 
 Doc/library/pdb.rst                   |    4 
 Doc/library/posix.rst                 |    2 
 Doc/library/pprint.rst                |    4 
 Doc/library/pwd.rst                   |    2 
 Doc/library/pyexpat.rst               |    2 
 Doc/library/runpy.rst                 |    4 
 Doc/library/shelve.rst                |    6 -
 Doc/library/site.rst                  |    6 -
 Doc/library/socket.rst                |    4 
 Doc/library/stdtypes.rst              |  146 ++++++++++++++++----------------
 Doc/library/sys.rst                   |    2 
 Doc/library/traceback.rst             |    2 
 Doc/library/types.rst                 |    2 
 Doc/reference/compound_stmts.rst      |   90 +++++++++----------
 Doc/reference/datamodel.rst           |  154 +++++++++++++++++-----------------
 Doc/reference/executionmodel.rst      |    2 
 Doc/reference/expressions.rst         |  134 ++++++++++++++---------------
 Doc/reference/simple_stmts.rst        |   74 ++++++++--------
 Doc/reference/toplevel_components.rst |   10 +-
 Doc/tools/extensions/pyspecific.py    |   25 +++++
 Doc/tutorial/classes.rst              |    2 
 Doc/tutorial/controlflow.rst          |    2 
 Doc/tutorial/inputoutput.rst          |    6 -
 Doc/tutorial/modules.rst              |    4 
 Doc/tutorial/stdlib.rst               |    2 
 71 files changed, 457 insertions(+), 427 deletions(-)

--- a/Doc/c-api/bytearray.rst
+++ b/Doc/c-api/bytearray.rst
@@ -5,7 +5,7 @@
 Byte Array Objects
 ------------------
 
-.. index:: object: bytearray
+.. index:: pair: object; bytearray
 
 
 .. c:type:: PyByteArrayObject
--- a/Doc/c-api/bytes.rst
+++ b/Doc/c-api/bytes.rst
@@ -8,7 +8,7 @@ Bytes Objects
 These functions raise :exc:`TypeError` when expecting a bytes parameter and
 called with a non-bytes parameter.
 
-.. index:: object: bytes
+.. index:: pair: object; bytes
 
 
 .. c:type:: PyBytesObject
--- a/Doc/c-api/capsule.rst
+++ b/Doc/c-api/capsule.rst
@@ -5,7 +5,7 @@
 Capsules
 --------
 
-.. index:: object: Capsule
+.. index:: pair: object; Capsule
 
 Refer to :ref:`using-capsules` for more information on using these objects.
 
--- a/Doc/c-api/complex.rst
+++ b/Doc/c-api/complex.rst
@@ -5,7 +5,7 @@
 Complex Number Objects
 ----------------------
 
-.. index:: object: complex number
+.. index:: pair: object; complex number
 
 Python's complex number objects are implemented as two distinct types when
 viewed from the C API:  one is the Python object exposed to Python programs, and
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -40,7 +40,7 @@ This section describes Python type objec
 Numeric Objects
 ===============
 
-.. index:: object: numeric
+.. index:: pair: object; numeric
 
 .. toctree::
 
@@ -55,7 +55,7 @@ Numeric Objects
 Sequence Objects
 ================
 
-.. index:: object: sequence
+.. index:: pair: object; sequence
 
 Generic operations on sequence objects were discussed in the previous chapter;
 this section deals with the specific kinds of sequence objects that are
@@ -77,7 +77,7 @@ intrinsic to the Python language.
 Container Objects
 =================
 
-.. index:: object: mapping
+.. index:: pair: object; mapping
 
 .. toctree::
 
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -5,7 +5,7 @@
 Dictionary Objects
 ------------------
 
-.. index:: object: dictionary
+.. index:: pair: object; dictionary
 
 
 .. c:type:: PyDictObject
@@ -154,7 +154,7 @@ Dictionary Objects
 
 .. c:function:: Py_ssize_t PyDict_Size(PyObject *p)
 
-   .. index:: builtin: len
+   .. index:: pair: built-in function; len
 
    Return the number of items in the dictionary.  This is equivalent to
    ``len(p)`` on a dictionary.
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -503,7 +503,7 @@ Signal Handling
 .. c:function:: int PyErr_CheckSignals()
 
    .. index::
-      module: signal
+      pair: module; signal
       single: SIGINT
       single: KeyboardInterrupt (built-in exception)
 
@@ -534,7 +534,7 @@ Signal Handling
 .. c:function:: void PyErr_SetInterrupt()
 
    .. index::
-      module: signal
+      pair: module; signal
       single: SIGINT
       single: KeyboardInterrupt (built-in exception)
 
@@ -549,7 +549,7 @@ Signal Handling
 .. c:function:: int PyErr_SetInterruptEx(int signum)
 
    .. index::
-      module: signal
+      pair: module; signal
       single: KeyboardInterrupt (built-in exception)
 
    Simulate the effect of a signal arriving. The next time
--- a/Doc/c-api/file.rst
+++ b/Doc/c-api/file.rst
@@ -5,7 +5,7 @@
 File Objects
 ------------
 
-.. index:: object: file
+.. index:: pair: object; file
 
 These APIs are a minimal emulation of the Python 2 C API for built-in file
 objects, which used to rely on the buffered I/O (:c:expr:`FILE*`) support
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -5,7 +5,7 @@
 Floating Point Objects
 ----------------------
 
-.. index:: object: floating point
+.. index:: pair: object; floating point
 
 
 .. c:type:: PyFloatObject
--- a/Doc/c-api/function.rst
+++ b/Doc/c-api/function.rst
@@ -5,7 +5,7 @@
 Function Objects
 ----------------
 
-.. index:: object: function
+.. index:: pair: object; function
 
 There are a few functions specific to Python functions.
 
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -41,7 +41,7 @@ Importing Modules
 
 .. c:function:: PyObject* PyImport_ImportModuleEx(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
 
-   .. index:: builtin: __import__
+   .. index:: pair: built-in function; __import__
 
    Import a module.  This is best described by referring to the built-in Python
    function :func:`__import__`.
@@ -120,7 +120,7 @@ Importing Modules
 
 .. c:function:: PyObject* PyImport_ExecCodeModule(const char *name, PyObject *co)
 
-   .. index:: builtin: compile
+   .. index:: pair: built-in function; compile
 
    Given a module name (possibly of the form ``package.module``) and a code object
    read from a Python bytecode file or obtained from the built-in function
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -233,9 +233,9 @@ Initializing and finalizing the interpre
       single: PyEval_InitThreads()
       single: modules (in module sys)
       single: path (in module sys)
-      module: builtins
-      module: __main__
-      module: sys
+      pair: module; builtins
+      pair: module; __main__
+      pair: module; sys
       triple: module; search; path
       single: PySys_SetArgv()
       single: PySys_SetArgvEx()
@@ -895,7 +895,7 @@ code, or when embedding the Python inter
 
    .. deprecated-removed:: 3.9 3.11
 
-   .. index:: module: _thread
+   .. index:: pair: module; _thread
 
 
 .. c:function:: int PyEval_ThreadsInitialized()
@@ -1315,9 +1315,9 @@ function. You can create and destroy the
 .. c:function:: PyThreadState* Py_NewInterpreter()
 
    .. index::
-      module: builtins
-      module: __main__
-      module: sys
+      pair: module; builtins
+      pair: module; __main__
+      pair: module; sys
       single: stdout (in module sys)
       single: stderr (in module sys)
       single: stdin (in module sys)
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -226,7 +226,7 @@ complete listing.
 Objects, Types and Reference Counts
 ===================================
 
-.. index:: object: type
+.. index:: pair: object; type
 
 Most Python/C API functions have one or more arguments as well as a return value
 of type :c:expr:`PyObject*`.  This type is a pointer to an opaque data type
@@ -677,9 +677,9 @@ interpreter can only be used after the i
 
 .. index::
    single: Py_Initialize()
-   module: builtins
-   module: __main__
-   module: sys
+   pair: module; builtins
+   pair: module; __main__
+   pair: module; sys
    triple: module; search; path
    single: path (in module sys)
 
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -5,7 +5,7 @@
 List Objects
 ------------
 
-.. index:: object: list
+.. index:: pair: object; list
 
 
 .. c:type:: PyListObject
@@ -45,7 +45,7 @@ List Objects
 
 .. c:function:: Py_ssize_t PyList_Size(PyObject *list)
 
-   .. index:: builtin: len
+   .. index:: pair: built-in function; len
 
    Return the length of the list object in *list*; this is equivalent to
    ``len(list)`` on a list object.
@@ -138,7 +138,7 @@ List Objects
 
 .. c:function:: PyObject* PyList_AsTuple(PyObject *list)
 
-   .. index:: builtin: tuple
+   .. index:: pair: built-in function; tuple
 
    Return a new tuple object containing the contents of *list*; equivalent to
    ``tuple(list)``.
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -5,8 +5,8 @@
 Integer Objects
 ---------------
 
-.. index:: object: long integer
-           object: integer
+.. index:: pair: object; long integer
+           pair: object; integer
 
 All integers are implemented as "long" integer objects of arbitrary size.
 
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -20,7 +20,7 @@ See also :c:func:`PyObject_GetItem`, :c:
 .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
                Py_ssize_t PyMapping_Length(PyObject *o)
 
-   .. index:: builtin: len
+   .. index:: pair: built-in function; len
 
    Returns the number of keys in object *o* on success, and ``-1`` on failure.
    This is equivalent to the Python expression ``len(o)``.
--- a/Doc/c-api/memoryview.rst
+++ b/Doc/c-api/memoryview.rst
@@ -3,7 +3,7 @@
 .. _memoryview-objects:
 
 .. index::
-   object: memoryview
+   pair: object; memoryview
 
 MemoryView objects
 ------------------
--- a/Doc/c-api/method.rst
+++ b/Doc/c-api/method.rst
@@ -5,7 +5,7 @@
 Instance Method Objects
 -----------------------
 
-.. index:: object: instancemethod
+.. index:: pair: object; instancemethod
 
 An instance method is a wrapper for a :c:data:`PyCFunction` and the new way
 to bind a :c:data:`PyCFunction` to a class object. It replaces the former call
@@ -47,7 +47,7 @@ to bind a :c:data:`PyCFunction` to a cla
 Method Objects
 --------------
 
-.. index:: object: method
+.. index:: pair: object; method
 
 Methods are bound function objects. Methods are always bound to an instance of
 a user-defined class. Unbound methods (methods bound to a class object) are
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -5,7 +5,7 @@
 Module Objects
 --------------
 
-.. index:: object: module
+.. index:: pair: object; module
 
 
 .. c:var:: PyTypeObject PyModule_Type
--- a/Doc/c-api/none.rst
+++ b/Doc/c-api/none.rst
@@ -5,7 +5,7 @@
 The ``None`` Object
 -------------------
 
-.. index:: object: None
+.. index:: pair: object; None
 
 Note that the :c:type:`PyTypeObject` for ``None`` is not directly exposed in the
 Python/C API.  Since ``None`` is a singleton, testing for object identity (using
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -64,7 +64,7 @@ Number Protocol
 
 .. c:function:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2)
 
-   .. index:: builtin: divmod
+   .. index:: pair: built-in function; divmod
 
    See the built-in function :func:`divmod`. Returns ``NULL`` on failure.  This is
    the equivalent of the Python expression ``divmod(o1, o2)``.
@@ -72,7 +72,7 @@ Number Protocol
 
 .. c:function:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3)
 
-   .. index:: builtin: pow
+   .. index:: pair: built-in function; pow
 
    See the built-in function :func:`pow`. Returns ``NULL`` on failure.  This is the
    equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional.
@@ -94,7 +94,7 @@ Number Protocol
 
 .. c:function:: PyObject* PyNumber_Absolute(PyObject *o)
 
-   .. index:: builtin: abs
+   .. index:: pair: built-in function; abs
 
    Returns the absolute value of *o*, or ``NULL`` on failure.  This is the equivalent
    of the Python expression ``abs(o)``.
@@ -192,7 +192,7 @@ Number Protocol
 
 .. c:function:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3)
 
-   .. index:: builtin: pow
+   .. index:: pair: built-in function; pow
 
    See the built-in function :func:`pow`. Returns ``NULL`` on failure.  The operation
    is done *in-place* when *o1* supports it.  This is the equivalent of the Python
@@ -238,7 +238,7 @@ Number Protocol
 
 .. c:function:: PyObject* PyNumber_Long(PyObject *o)
 
-   .. index:: builtin: int
+   .. index:: pair: built-in function; int
 
    Returns the *o* converted to an integer object on success, or ``NULL`` on
    failure.  This is the equivalent of the Python expression ``int(o)``.
@@ -246,7 +246,7 @@ Number Protocol
 
 .. c:function:: PyObject* PyNumber_Float(PyObject *o)
 
-   .. index:: builtin: float
+   .. index:: pair: built-in function; float
 
    Returns the *o* converted to a float object on success, or ``NULL`` on failure.
    This is the equivalent of the Python expression ``float(o)``.
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -172,7 +172,7 @@ Object Protocol
 
 .. c:function:: PyObject* PyObject_Repr(PyObject *o)
 
-   .. index:: builtin: repr
+   .. index:: pair: built-in function; repr
 
    Compute a string representation of object *o*.  Returns the string
    representation on success, ``NULL`` on failure.  This is the equivalent of the
@@ -184,7 +184,7 @@ Object Protocol
 
 .. c:function:: PyObject* PyObject_ASCII(PyObject *o)
 
-   .. index:: builtin: ascii
+   .. index:: pair: built-in function; ascii
 
    As :c:func:`PyObject_Repr`, compute a string representation of object *o*, but
    escape the non-ASCII characters in the string returned by
@@ -209,7 +209,7 @@ Object Protocol
 
 .. c:function:: PyObject* PyObject_Bytes(PyObject *o)
 
-   .. index:: builtin: bytes
+   .. index:: pair: built-in function; bytes
 
    Compute a bytes representation of object *o*.  ``NULL`` is returned on
    failure and a bytes object on success.  This is equivalent to the Python
@@ -260,7 +260,7 @@ Object Protocol
 
 .. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
 
-   .. index:: builtin: hash
+   .. index:: pair: built-in function; hash
 
    Compute and return the hash value of an object *o*.  On failure, return ``-1``.
    This is the equivalent of the Python expression ``hash(o)``.
@@ -294,7 +294,7 @@ Object Protocol
 
 .. c:function:: PyObject* PyObject_Type(PyObject *o)
 
-   .. index:: builtin: type
+   .. index:: pair: built-in function; type
 
    When *o* is non-``NULL``, returns a type object corresponding to the object type
    of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``.  This
@@ -315,7 +315,7 @@ Object Protocol
 .. c:function:: Py_ssize_t PyObject_Size(PyObject *o)
                Py_ssize_t PyObject_Length(PyObject *o)
 
-   .. index:: builtin: len
+   .. index:: pair: built-in function; len
 
    Return the length of object *o*.  If the object *o* provides either the sequence
    and mapping protocols, the sequence length is returned.  On error, ``-1`` is
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -18,7 +18,7 @@ Sequence Protocol
 .. c:function:: Py_ssize_t PySequence_Size(PyObject *o)
                Py_ssize_t PySequence_Length(PyObject *o)
 
-   .. index:: builtin: len
+   .. index:: pair: built-in function; len
 
    Returns the number of objects in sequence *o* on success, and ``-1`` on
    failure.  This is equivalent to the Python expression ``len(o)``.
@@ -120,7 +120,7 @@ Sequence Protocol
 
 .. c:function:: PyObject* PySequence_Tuple(PyObject *o)
 
-   .. index:: builtin: tuple
+   .. index:: pair: built-in function; tuple
 
    Return a tuple object with the same contents as the sequence or iterable *o*,
    or ``NULL`` on failure.  If *o* is a tuple, a new reference will be returned,
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -9,8 +9,8 @@ Set Objects
 
 
 .. index::
-   object: set
-   object: frozenset
+   pair: object; set
+   pair: object; frozenset
 
 This section details the public API for :class:`set` and :class:`frozenset`
 objects.  Any functionality not listed below is best accessed using either
@@ -107,7 +107,7 @@ or :class:`frozenset` or instances of th
 
 .. c:function:: Py_ssize_t PySet_Size(PyObject *anyset)
 
-   .. index:: builtin: len
+   .. index:: pair: built-in function; len
 
    Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to
    ``len(anyset)``.  Raises a :exc:`PyExc_SystemError` if *anyset* is not a
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -351,7 +351,7 @@ method.
 
 .. data:: METH_CLASS
 
-   .. index:: builtin: classmethod
+   .. index:: pair: built-in function; classmethod
 
    The method will be passed the type object as the first parameter rather
    than an instance of the type.  This is used to create *class methods*,
@@ -361,7 +361,7 @@ method.
 
 .. data:: METH_STATIC
 
-   .. index:: builtin: staticmethod
+   .. index:: pair: built-in function; staticmethod
 
    The method will be passed ``NULL`` as the first parameter rather than an
    instance of the type.  This is used to create *static methods*, similar to
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -5,7 +5,7 @@
 Tuple Objects
 -------------
 
-.. index:: object: tuple
+.. index:: pair: object; tuple
 
 
 .. c:type:: PyTupleObject
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -5,7 +5,7 @@
 Type Objects
 ------------
 
-.. index:: object: type
+.. index:: pair: object; type
 
 
 .. c:type:: PyTypeObject
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -803,7 +803,7 @@ and :c:type:`PyType_Type` effectively ac
 
 .. c:member:: reprfunc PyTypeObject.tp_repr
 
-   .. index:: builtin: repr
+   .. index:: pair: built-in function; repr
 
    An optional pointer to a function that implements the built-in function
    :func:`repr`.
@@ -868,7 +868,7 @@ and :c:type:`PyType_Type` effectively ac
 
 .. c:member:: hashfunc PyTypeObject.tp_hash
 
-   .. index:: builtin: hash
+   .. index:: pair: built-in function; hash
 
    An optional pointer to a function that implements the built-in function
    :func:`hash`.
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -61,6 +61,11 @@ smartquotes_excludes = {
 # Avoid a warning with Sphinx >= 2.0
 master_doc = 'contents'
 
+# Allow translation of index directives
+gettext_additional_targets = [
+    'index',
+]
+
 # Options for HTML output
 # -----------------------
 
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -149,7 +149,7 @@ done.  This can be done using the :c:fun
 
 .. index::
    single: string; object representation
-   builtin: repr
+   pair: built-in function; repr
 
 Object Presentation
 -------------------
--- a/Doc/library/_thread.rst
+++ b/Doc/library/_thread.rst
@@ -204,7 +204,7 @@ In addition to these methods, lock objec
 
 **Caveats:**
 
-  .. index:: module: signal
+  .. index:: pair: module; signal
 
 * Threads interact strangely with interrupts: the :exc:`KeyboardInterrupt`
   exception will be received by an arbitrary thread.  (When the :mod:`signal`
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -6,9 +6,9 @@
               representations.
 
 .. index::
-   module: uu
-   module: base64
-   module: binhex
+   pair: module; uu
+   pair: module; base64
+   pair: module; binhex
 
 --------------
 
--- a/Doc/library/cmath.rst
+++ b/Doc/library/cmath.rst
@@ -301,7 +301,7 @@ Constants
    .. versionadded:: 3.6
 
 
-.. index:: module: math
+.. index:: pair: module; math
 
 Note that the selection of functions is similar, but not identical, to that in
 module :mod:`math`.  The reason for having two modules is that some users aren't
--- a/Doc/library/copy.rst
+++ b/Doc/library/copy.rst
@@ -68,7 +68,7 @@ Shallow copies of dictionaries can be ma
 of lists by assigning a slice of the entire list, for example,
 ``copied_list = original_list[:]``.
 
-.. index:: module: pickle
+.. index:: pair: module; pickle
 
 Classes can use the same interfaces to control copying that they use to control
 pickling.  See the description of module :mod:`pickle` for information on these
--- a/Doc/library/copyreg.rst
+++ b/Doc/library/copyreg.rst
@@ -7,8 +7,8 @@
 **Source code:** :source:`Lib/copyreg.py`
 
 .. index::
-   module: pickle
-   module: copy
+   pair: module; pickle
+   pair: module; copy
 
 --------------
 
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -1207,7 +1207,7 @@ All of the following opcodes use their a
 
 .. opcode:: BUILD_SLICE (argc)
 
-   .. index:: builtin: slice
+   .. index:: pair: built-in function; slice
 
    Pushes a slice object on the stack.  *argc* must be 2 or 3.  If it is 2,
    ``slice(TOS1, TOS)`` is pushed; if it is 3, ``slice(TOS2, TOS1, TOS)`` is
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -4,8 +4,8 @@ Built-in Exceptions
 ===================
 
 .. index::
-   statement: try
-   statement: except
+   pair: statement; try
+   pair: statement; except
 
 In Python, all exceptions must be instances of a class that derives from
 :class:`BaseException`.  In a :keyword:`try` statement with an :keyword:`except`
@@ -14,7 +14,7 @@ classes derived from that class (but not
 derived).  Two exception classes that are not related via subclassing are never
 equivalent, even if they have the same name.
 
-.. index:: statement: raise
+.. index:: pair: statement; raise
 
 The built-in exceptions listed below can be generated by the interpreter or
 built-in functions.  Except where mentioned, they have an "associated value"
@@ -160,7 +160,7 @@ The following exceptions are the excepti
 
 .. exception:: AssertionError
 
-   .. index:: statement: assert
+   .. index:: pair: statement; assert
 
    Raised when an :keyword:`assert` statement fails.
 
@@ -303,7 +303,7 @@ The following exceptions are the excepti
 .. exception:: OSError([arg])
                OSError(errno, strerror[, filename[, winerror[, filename2]]])
 
-   .. index:: module: errno
+   .. index:: pair: module; errno
 
    This exception is raised when a system function returns a system-related
    error, including I/O failures such as "file not found" or "disk full"
--- a/Doc/library/fnmatch.rst
+++ b/Doc/library/fnmatch.rst
@@ -8,7 +8,7 @@
 
 .. index:: single: filenames; wildcard expansion
 
-.. index:: module: re
+.. index:: pair: module; re
 
 --------------
 
@@ -38,7 +38,7 @@ special characters used in shell-style w
 For a literal match, wrap the meta-characters in brackets.
 For example, ``'[?]'`` matches the character ``'?'``.
 
-.. index:: module: glob
+.. index:: pair: module; glob
 
 Note that the filename separator (``'/'`` on Unix) is *not* special to this
 module.  See module :mod:`glob` for pathname expansion (:mod:`glob` uses
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -548,7 +548,7 @@ are always available.  They are listed h
       Raises an :ref:`auditing event <auditing>` ``exec`` with the code object
       as the argument. Code compilation events may also be raised.
 
-.. index:: builtin: exec
+.. index:: pair: built-in function; exec
 
 .. function:: exec(object[, globals[, locals]])
 
@@ -1314,7 +1314,7 @@ are always available.  They are listed h
       single: I/O control; buffering
       single: binary mode
       single: text mode
-      module: sys
+      pair: module; sys
 
    See also the file handling modules, such as :mod:`fileinput`, :mod:`io`
    (where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`,
@@ -1799,7 +1799,7 @@ are always available.  They are listed h
 .. class:: type(object)
            type(name, bases, dict, **kwds)
 
-   .. index:: object: type
+   .. index:: pair: object; type
 
    With one argument, return the type of an *object*.  The return value is a
    type object and generally the same object as returned by
@@ -1954,8 +1954,8 @@ are always available.  They are listed h
 .. function:: __import__(name, globals=None, locals=None, fromlist=(), level=0)
 
    .. index::
-      statement: import
-      module: imp
+      pair: statement; import
+      pair: module; builtins
 
    .. note::
 
--- a/Doc/library/http.client.rst
+++ b/Doc/library/http.client.rst
@@ -10,7 +10,7 @@
    pair: HTTP; protocol
    single: HTTP; http.client (standard module)
 
-.. index:: module: urllib.request
+.. index:: pair: module; urllib.request
 
 --------------
 
--- a/Doc/library/imp.rst
+++ b/Doc/library/imp.rst
@@ -10,7 +10,7 @@
 .. deprecated:: 3.4
    The :mod:`imp` module is deprecated in favor of :mod:`importlib`.
 
-.. index:: statement: import
+.. index:: pair: statement; import
 
 --------------
 
--- a/Doc/library/internet.rst
+++ b/Doc/library/internet.rst
@@ -9,7 +9,7 @@ Internet Protocols and Support
    single: Internet
    single: World Wide Web
 
-.. index:: module: socket
+.. index:: pair: module; socket
 
 The modules described in this chapter implement internet protocols and  support
 for related technology.  They are all implemented in Python. Most of these
--- a/Doc/library/locale.rst
+++ b/Doc/library/locale.rst
@@ -16,7 +16,7 @@ functionality. The POSIX locale mechanis
 certain cultural issues in an application, without requiring the programmer to
 know all the specifics of each country where the software is executed.
 
-.. index:: module: _locale
+.. index:: pair: module; _locale
 
 The :mod:`locale` module is implemented on top of the :mod:`_locale` module,
 which in turn uses an ANSI C locale implementation if available.
@@ -452,7 +452,7 @@ The :mod:`locale` module defines the fol
 
 .. data:: LC_CTYPE
 
-   .. index:: module: string
+   .. index:: pair: module; string
 
    Locale category for the character type functions.  Depending on the settings of
    this category, the functions of module :mod:`string` dealing with case change
--- a/Doc/library/marshal.rst
+++ b/Doc/library/marshal.rst
@@ -15,8 +15,8 @@ undocumented on purpose; it may change b
 rarely does). [#]_
 
 .. index::
-   module: pickle
-   module: shelve
+   pair: module; pickle
+   pair: module; shelve
 
 This is not a general "persistence" module.  For general persistence and
 transfer of Python objects through RPC calls, see the modules :mod:`pickle` and
--- a/Doc/library/os.path.rst
+++ b/Doc/library/os.path.rst
@@ -159,7 +159,7 @@ the :mod:`glob` module.)
    On Unix and Windows, return the argument with an initial component of ``~`` or
    ``~user`` replaced by that *user*'s home directory.
 
-   .. index:: module: pwd
+   .. index:: pair: module; pwd
 
    On Unix, an initial ``~`` is replaced by the environment variable :envvar:`HOME`
    if it is set; otherwise the current user's home directory is looked up in the
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -1136,7 +1136,7 @@ or `the MSDN <https://msdn.microsoft.com
 
 .. function:: openpty()
 
-   .. index:: module: pty
+   .. index:: pair: module; pty
 
    Open a new pseudo-terminal pair. Return a pair of file descriptors
    ``(master, slave)`` for the pty and the tty, respectively. The new file
@@ -2644,7 +2644,7 @@ features:
    possible and call :func:`lstat` on the result. This does not apply to
    dangling symlinks or junction points, which will raise the usual exceptions.
 
-   .. index:: module: stat
+   .. index:: pair: module; stat
 
    Example::
 
--- a/Doc/library/pdb.rst
+++ b/Doc/library/pdb.rst
@@ -20,8 +20,8 @@ supports post-mortem debugging and can b
 
 .. index::
    single: Pdb (class in pdb)
-   module: bdb
-   module: cmd
+   pair: module; bdb
+   pair: module; cmd
 
 The debugger is extensible -- it is actually defined as the class :class:`Pdb`.
 This is currently undocumented but easily understood by reading the source.  The
--- a/Doc/library/posix.rst
+++ b/Doc/library/posix.rst
@@ -11,7 +11,7 @@ This module provides access to operating
 standardized by the C Standard and the POSIX standard (a thinly disguised Unix
 interface).
 
-.. index:: module: os
+.. index:: pair: module; os
 
 **Do not import this module directly.**  Instead, import the module :mod:`os`,
 which provides a *portable* version of this interface.  On Unix, the :mod:`os`
--- a/Doc/library/pprint.rst
+++ b/Doc/library/pprint.rst
@@ -171,7 +171,7 @@ The :mod:`pprint` module also provides s
 
 .. function:: isreadable(object)
 
-   .. index:: builtin: eval
+   .. index:: pair: built-in function; eval
 
    Determine if the formatted representation of *object* is "readable", or can be
    used to reconstruct the value using :func:`eval`.  This always returns ``False``
@@ -226,7 +226,7 @@ created.
 
 .. method:: PrettyPrinter.isreadable(object)
 
-   .. index:: builtin: eval
+   .. index:: pair: built-in function; eval
 
    Determine if the formatted representation of the object is "readable," or can be
    used to reconstruct the value using :func:`eval`.  Note that this returns
--- a/Doc/library/pwd.rst
+++ b/Doc/library/pwd.rst
@@ -37,7 +37,7 @@ raised if the entry asked for cannot be
 
 .. note::
 
-   .. index:: module: crypt
+   .. index:: pair: module; crypt
 
    In traditional Unix the field ``pw_passwd`` usually contains a password
    encrypted with a DES derived algorithm (see module :mod:`crypt`).  However most
--- a/Doc/library/pyexpat.rst
+++ b/Doc/library/pyexpat.rst
@@ -33,7 +33,7 @@ can be set to handler functions.  When a
 parser, the handler functions are called for the character data and markup in
 the XML document.
 
-.. index:: module: pyexpat
+.. index:: pair: module; pyexpat
 
 This module uses the :mod:`pyexpat` module to provide access to the Expat
 parser.  Direct use of the :mod:`pyexpat` module is deprecated.
--- a/Doc/library/runpy.rst
+++ b/Doc/library/runpy.rst
@@ -30,7 +30,7 @@ The :mod:`runpy` module provides two fun
 .. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)
 
    .. index::
-      module: __main__
+      pair: module; __main__
 
    Execute the code of the specified module and return the resulting module
    globals dictionary. The module's code is first located using the standard
@@ -96,7 +96,7 @@ The :mod:`runpy` module provides two fun
 .. function:: run_path(path_name, init_globals=None, run_name=None)
 
    .. index::
-      module: __main__
+      pair: module; __main__
 
    Execute the code at the named filesystem location and return the resulting
    module globals dictionary. As with a script name supplied to the CPython
--- a/Doc/library/shelve.rst
+++ b/Doc/library/shelve.rst
@@ -6,7 +6,7 @@
 
 **Source code:** :source:`Lib/shelve.py`
 
-.. index:: module: pickle
+.. index:: pair: module; pickle
 
 --------------
 
@@ -92,8 +92,8 @@ Restrictions
 ------------
 
   .. index::
-     module: dbm.ndbm
-     module: dbm.gnu
+     pair: module; dbm.ndbm
+     pair: module; dbm.gnu
 
 * The choice of which database package will be used (such as :mod:`dbm.ndbm` or
   :mod:`dbm.gnu`) depends on which interface is available.  Therefore it is not
--- a/Doc/library/site.rst
+++ b/Doc/library/site.rst
@@ -51,7 +51,7 @@ searched for site-packages; otherwise th
 
 .. index::
    single: # (hash); comment
-   statement: import
+   pair: statement; import
 
 A path configuration file is a file whose name has the form :file:`{name}.pth`
 and exists in one of the four directories mentioned above; its contents are
@@ -109,7 +109,7 @@ directory precedes the :file:`foo` direc
 alphabetically before :file:`foo.pth`; and :file:`spam` is omitted because it is
 not mentioned in either path configuration file.
 
-.. index:: module: sitecustomize
+.. index:: pair: module; sitecustomize
 
 After these path manipulations, an attempt is made to import a module named
 :mod:`sitecustomize`, which can perform arbitrary site-specific customizations.
@@ -121,7 +121,7 @@ with :file:`pythonw.exe` on Windows (whi
 attempted output from :mod:`sitecustomize` is ignored.  Any other exception
 causes a silent and perhaps mysterious failure of the process.
 
-.. index:: module: usercustomize
+.. index:: pair: module; usercustomize
 
 After this, an attempt is made to import a module named :mod:`usercustomize`,
 which can perform arbitrary user-specific customizations, if
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -16,7 +16,7 @@ all modern Unix systems, Windows, MacOS,
    Some behavior may be platform dependent, since calls are made to the operating
    system socket APIs.
 
-.. index:: object: socket
+.. index:: pair: object; socket
 
 The Python interface is a straightforward transliteration of the Unix system
 call and library interface for sockets to Python's object-oriented style: the
@@ -1735,7 +1735,7 @@ to sockets.
 .. method:: socket.setsockopt(level, optname, None, optlen: int)
    :noindex:
 
-   .. index:: module: struct
+   .. index:: pair: module; struct
 
    Set the value of the given socket option (see the Unix manual page
    :manpage:`setsockopt(2)`).  The needed symbolic constants are defined in the
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -32,8 +32,8 @@ Truth Value Testing
 ===================
 
 .. index::
-   statement: if
-   statement: while
+   pair: statement; if
+   pair: statement; while
    pair: truth; value
    pair: Boolean; operations
    single: false
@@ -61,8 +61,8 @@ objects considered false:
   ``range(0)``
 
 .. index::
-   operator: or
-   operator: and
+   pair: operator; or
+   pair: operator; and
    single: False
    single: True
 
@@ -95,9 +95,9 @@ These are the Boolean operations, ordere
 +-------------+---------------------------------+-------+
 
 .. index::
-   operator: and
-   operator: or
-   operator: not
+   pair: operator; and
+   pair: operator; or
+   pair: operator; not
 
 Notes:
 
@@ -122,14 +122,14 @@ Comparisons
 .. index::
    pair: chaining; comparisons
    pair: operator; comparison
-   operator: ==
-   operator: < (less)
-   operator: <=
-   operator: > (greater)
-   operator: >=
-   operator: !=
-   operator: is
-   operator: is not
+   pair: operator; ==
+   pair: operator; < (less)
+   pair: operator; <=
+   pair: operator; > (greater)
+   pair: operator; >=
+   pair: operator; !=
+   pair: operator; is
+   pair: operator; is not
 
 There are eight comparison operations in Python.  They all have the same
 priority (which is higher than that of the Boolean operations).  Comparisons can
@@ -192,8 +192,8 @@ customized; also they can be applied to
 exception.
 
 .. index::
-   operator: in
-   operator: not in
+   pair: operator; in
+   pair: operator; not in
 
 Two more operations with the same syntactic priority, :keyword:`in` and
 :keyword:`not in`, are supported by types that are :term:`iterable` or
@@ -205,11 +205,11 @@ Numeric Types --- :class:`int`, :class:`
 ================================================================
 
 .. index::
-   object: numeric
-   object: Boolean
-   object: integer
-   object: floating point
-   object: complex number
+   pair: object; numeric
+   pair: object; Boolean
+   pair: object; integer
+   pair: object; floating point
+   pair: object; complex number
    pair: C; language
 
 There are three distinct numeric types: :dfn:`integers`, :dfn:`floating
@@ -244,20 +244,20 @@ and imaginary parts.
 
 .. index::
    single: arithmetic
-   builtin: int
-   builtin: float
-   builtin: complex
+   pair: built-in function; int
+   pair: built-in function; float
+   pair: built-in function; complex
    single: operator; + (plus)
    single: + (plus); unary operator
    single: + (plus); binary operator
    single: operator; - (minus)
    single: - (minus); unary operator
    single: - (minus); binary operator
-   operator: * (asterisk)
-   operator: / (slash)
-   operator: //
-   operator: % (percent)
-   operator: **
+   pair: operator; * (asterisk)
+   pair: operator; / (slash)
+   pair: operator; //
+   pair: operator; % (percent)
+   pair: operator; **
 
 Python fully supports mixed arithmetic: when a binary arithmetic operator has
 operands of different numeric types, the operand with the "narrower" type is
@@ -330,7 +330,7 @@ Notes:
 
 (3)
    .. index::
-      module: math
+      pair: module; math
       single: floor() (in module math)
       single: ceil() (in module math)
       single: trunc() (in module math)
@@ -392,12 +392,12 @@ Bitwise Operations on Integer Types
    pair: bitwise; operations
    pair: shifting; operations
    pair: masking; operations
-   operator: | (vertical bar)
-   operator: ^ (caret)
-   operator: & (ampersand)
-   operator: <<
-   operator: >>
-   operator: ~ (tilde)
+   pair: operator; | (vertical bar)
+   pair: operator; ^ (caret)
+   pair: operator; & (ampersand)
+   pair: operator; <<
+   pair: operator; >>
+   pair: operator; ~ (tilde)
 
 Bitwise operations only make sense for integers. The result of bitwise
 operations is calculated as though carried out in two's complement with an
@@ -848,7 +848,7 @@ described in dedicated sections.
 Common Sequence Operations
 --------------------------
 
-.. index:: object: sequence
+.. index:: pair: object; sequence
 
 The operations in the following table are supported by most sequence types,
 both mutable and immutable. The :class:`collections.abc.Sequence` ABC is
@@ -866,15 +866,15 @@ operations have the same priority as the
 
 .. index::
    triple: operations on; sequence; types
-   builtin: len
-   builtin: min
-   builtin: max
+   pair: built-in function; len
+   pair: built-in function; min
+   pair: built-in function; max
    pair: concatenation; operation
    pair: repetition; operation
    pair: subscript; operation
    pair: slice; operation
-   operator: in
-   operator: not in
+   pair: operator; in
+   pair: operator; not in
    single: count() (sequence method)
    single: index() (sequence method)
 
@@ -1033,8 +1033,8 @@ Immutable Sequence Types
 
 .. index::
    triple: immutable; sequence; types
-   object: tuple
-   builtin: hash
+   pair: object; tuple
+   pair: built-in function; hash
 
 The only operation that immutable sequence types generally implement that is
 not also implemented by mutable sequence types is support for the :func:`hash`
@@ -1055,8 +1055,8 @@ Mutable Sequence Types
 
 .. index::
    triple: mutable; sequence; types
-   object: list
-   object: bytearray
+   pair: object; list
+   pair: object; bytearray
 
 The operations in the following table are defined on mutable sequence types.
 The :class:`collections.abc.MutableSequence` ABC is provided to make it
@@ -1073,7 +1073,7 @@ accepts integers that meet the value res
    triple: operations on; list; type
    pair: subscript; assignment
    pair: slice; assignment
-   statement: del
+   pair: statement; del
    single: append() (sequence method)
    single: clear() (sequence method)
    single: copy() (sequence method)
@@ -1173,7 +1173,7 @@ Notes:
 Lists
 -----
 
-.. index:: object: list
+.. index:: pair: object; list
 
 Lists are mutable sequences, typically used to store collections of
 homogeneous items (where the precise degree of similarity will vary by
@@ -1252,7 +1252,7 @@ application).
 Tuples
 ------
 
-.. index:: object: tuple
+.. index:: pair: object; tuple
 
 Tuples are immutable sequences, typically used to store collections of
 heterogeneous data (such as the 2-tuples produced by the :func:`enumerate`
@@ -1296,7 +1296,7 @@ choice than a simple tuple object.
 Ranges
 ------
 
-.. index:: object: range
+.. index:: pair: object; range
 
 The :class:`range` type represents an immutable sequence of numbers and is
 commonly used for looping a specific number of times in :keyword:`for`
@@ -1421,7 +1421,7 @@ objects that compare equal might have di
 .. index::
    single: string; text sequence type
    single: str (built-in class); (see also string)
-   object: string
+   pair: object; string
 
 .. _textseq:
 
@@ -1455,7 +1455,7 @@ Since there is no separate "character" t
 strings of length 1. That is, for a non-empty string *s*, ``s[0] == s[0:1]``.
 
 .. index::
-   object: io.StringIO
+   pair: object; io.StringIO
 
 There is also no mutable string type, but :meth:`str.join` or
 :class:`io.StringIO` can be used to efficiently construct strings from
@@ -1521,7 +1521,7 @@ String Methods
 --------------
 
 .. index::
-   module: re
+   pair: module; re
 
 Strings implement all of the :ref:`common <typesseq-common>` sequence
 operations, along with the additional methods described below.
@@ -2422,10 +2422,10 @@ Binary Sequence Types --- :class:`bytes`
 =================================================================================
 
 .. index::
-   object: bytes
-   object: bytearray
-   object: memoryview
-   module: array
+   pair: object; bytes
+   pair: object; bytearray
+   pair: object; memoryview
+   pair: module; array
 
 The core built-in types for manipulating binary data are :class:`bytes` and
 :class:`bytearray`. They are supported by :class:`memoryview` which uses
@@ -2440,7 +2440,7 @@ The :mod:`array` module supports efficie
 Bytes Objects
 -------------
 
-.. index:: object: bytes
+.. index:: pair: object; bytes
 
 Bytes objects are immutable sequences of single bytes. Since many major
 binary protocols are based on the ASCII text encoding, bytes objects offer
@@ -2547,7 +2547,7 @@ always convert a bytes object into a lis
 Bytearray Objects
 -----------------
 
-.. index:: object: bytearray
+.. index:: pair: object; bytearray
 
 :class:`bytearray` objects are a mutable counterpart to :class:`bytes`
 objects.
@@ -4123,7 +4123,7 @@ copying.
 Set Types --- :class:`set`, :class:`frozenset`
 ==============================================
 
-.. index:: object: set
+.. index:: pair: object; set
 
 A :dfn:`set` object is an unordered collection of distinct :term:`hashable` objects.
 Common uses include membership testing, removing duplicates from a sequence, and
@@ -4325,12 +4325,12 @@ Mapping Types --- :class:`dict`
 ===============================
 
 .. index::
-   object: mapping
-   object: dictionary
+   pair: object; mapping
+   pair: object; dictionary
    triple: operations on; mapping; types
    triple: operations on; dictionary; type
-   statement: del
-   builtin: len
+   pair: statement; del
+   pair: built-in function; len
 
 A :term:`mapping` object maps :term:`hashable` values to arbitrary objects.
 Mappings are mutable objects.  There is currently only one standard mapping
@@ -4794,7 +4794,7 @@ Generic Alias Type
 ------------------
 
 .. index::
-   object: GenericAlias
+   pair: object; GenericAlias
    pair: Generic; Alias
 
 ``GenericAlias`` objects are generally created by
@@ -5040,7 +5040,7 @@ Union Type
 ----------
 
 .. index::
-   object: Union
+   pair: object; Union
    pair: union; type
 
 A union object holds the value of the ``|`` (bitwise or) operation on
@@ -5197,7 +5197,7 @@ See :ref:`function` for more information
 Methods
 -------
 
-.. index:: object: method
+.. index:: pair: object; method
 
 Methods are functions that are called using the attribute notation. There are
 two flavors: built-in methods (such as :meth:`append` on lists) and class
@@ -5244,7 +5244,7 @@ Code Objects
 ------------
 
 .. index::
-   builtin: compile
+   pair: built-in function; compile
    single: __code__ (function object attribute)
 
 Code objects are used by the implementation to represent "pseudo-compiled"
@@ -5258,8 +5258,8 @@ Accessing ``__code__`` raises an :ref:`a
 ``object.__getattr__`` with arguments ``obj`` and ``"__code__"``.
 
 .. index::
-   builtin: exec
-   builtin: eval
+   pair: built-in function; exec
+   pair: built-in function; eval
 
 A code object can be executed or evaluated by passing it (instead of a source
 string) to the :func:`exec` or :func:`eval`  built-in functions.
@@ -5273,8 +5273,8 @@ Type Objects
 ------------
 
 .. index::
-   builtin: type
-   module: types
+   pair: built-in function; type
+   pair: module; types
 
 Type objects represent the various object types.  An object's type is accessed
 by the built-in function :func:`type`.  There are no special operations on
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -398,7 +398,7 @@ always available.
    an except clause."  For any stack frame, only information about the exception
    being currently handled is accessible.
 
-   .. index:: object: traceback
+   .. index:: pair: object; traceback
 
    If no exception is being handled anywhere on the stack, a tuple containing
    three ``None`` values is returned.  Otherwise, the values returned are
--- a/Doc/library/traceback.rst
+++ b/Doc/library/traceback.rst
@@ -14,7 +14,7 @@ interpreter when it prints a stack trace
 stack traces under program control, such as in a "wrapper" around the
 interpreter.
 
-.. index:: object: traceback
+.. index:: pair: object; traceback
 
 The module uses traceback objects --- this is the object type that is stored in
 the :data:`sys.last_traceback` variable and returned as the third item from
--- a/Doc/library/types.rst
+++ b/Doc/library/types.rst
@@ -146,7 +146,7 @@ Standard names are defined for the follo
 
 .. class:: CodeType(**kwargs)
 
-   .. index:: builtin: compile
+   .. index:: pair: built-in function; compile
 
    The type for code objects such as returned by :func:`compile`.
 
--- a/Doc/reference/compound_stmts.rst
+++ b/Doc/reference/compound_stmts.rst
@@ -84,9 +84,9 @@ The :keyword:`!if` statement
 ============================
 
 .. index::
-   ! statement: if
-   keyword: elif
-   keyword: else
+   ! pair: statement; if
+   pair: keyword; elif
+   pair: keyword; else
    single: : (colon); compound statement
 
 The :keyword:`if` statement is used for conditional execution:
@@ -109,8 +109,8 @@ The :keyword:`!while` statement
 ===============================
 
 .. index::
-   ! statement: while
-   keyword: else
+   ! pair: statement; while
+   pair: keyword; else
    pair: loop; statement
    single: : (colon); compound statement
 
@@ -127,8 +127,8 @@ suite of the :keyword:`!else` clause, if
 terminates.
 
 .. index::
-   statement: break
-   statement: continue
+   pair: statement; break
+   pair: statement; continue
 
 A :keyword:`break` statement executed in the first suite terminates the loop
 without executing the :keyword:`!else` clause's suite.  A :keyword:`continue`
@@ -142,12 +142,12 @@ The :keyword:`!for` statement
 =============================
 
 .. index::
-   ! statement: for
-   keyword: in
-   keyword: else
+   ! pair: statement; for
+   pair: keyword; in
+   pair: keyword; else
    pair: target; list
    pair: loop; statement
-   object: sequence
+   pair: object; sequence
    single: : (colon); compound statement
 
 The :keyword:`for` statement is used to iterate over the elements of a sequence
@@ -167,8 +167,8 @@ is empty or an iterator raises a :exc:`S
 the :keyword:`!else` clause, if present, is executed, and the loop terminates.
 
 .. index::
-   statement: break
-   statement: continue
+   pair: statement; break
+   pair: statement; continue
 
 A :keyword:`break` statement executed in the first suite terminates the loop
 without executing the :keyword:`!else` clause's suite.  A :keyword:`continue`
@@ -188,7 +188,7 @@ those made in the suite of the for-loop:
 
 
 .. index::
-   builtin: range
+   pair: built-in function; range
 
 Names in the target list are not deleted when the loop is finished, but if the
 sequence is empty, they will not have been assigned to at all by the loop.  Hint:
@@ -204,11 +204,11 @@ The :keyword:`!try` statement
 =============================
 
 .. index::
-   ! statement: try
-   keyword: except
-   keyword: finally
-   keyword: else
-   keyword: as
+   ! pair: statement; try
+   pair: keyword; except
+   pair: keyword; finally
+   pair: keyword; else
+   pair: keyword; as
    single: : (colon); compound statement
 
 The :keyword:`try` statement specifies exception handlers and/or cleanup code
@@ -275,8 +275,8 @@ traceback attached to them, they form a
 keeping all locals in that frame alive until the next garbage collection occurs.
 
 .. index::
-   module: sys
-   object: traceback
+   pair: module; sys
+   pair: object; traceback
 
 Before an except clause's suite is executed, details about the exception are
 stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`.
@@ -305,10 +305,10 @@ when leaving an exception handler::
    (None, None, None)
 
 .. index::
-   keyword: else
-   statement: return
-   statement: break
-   statement: continue
+   pair: keyword; else
+   pair: statement; return
+   pair: statement; break
+   pair: statement; continue
 
 The optional :keyword:`!else` clause is executed if the control flow leaves the
 :keyword:`try` suite, no exception was raised, and no :keyword:`return`,
@@ -316,7 +316,7 @@ The optional :keyword:`!else` clause is
 the :keyword:`!else` clause are not handled by the preceding :keyword:`except`
 clauses.
 
-.. index:: keyword: finally
+.. index:: pair: keyword; finally
 
 If :keyword:`finally` is present, it specifies a 'cleanup' handler.  The
 :keyword:`try` clause is executed, including any :keyword:`except` and
@@ -341,9 +341,9 @@ The exception information is not availab
 the :keyword:`finally` clause.
 
 .. index::
-   statement: return
-   statement: break
-   statement: continue
+   pair: statement; return
+   pair: statement; break
+   pair: statement; continue
 
 When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is
 executed in the :keyword:`try` suite of a :keyword:`!try`...\ :keyword:`!finally`
@@ -379,8 +379,8 @@ The :keyword:`!with` statement
 ==============================
 
 .. index::
-   ! statement: with
-   keyword: as
+   ! pair: statement; with
+   pair: keyword; as
    single: as; with statement
    single: , (comma); with statement
    single: : (colon); compound statement
@@ -496,11 +496,11 @@ The :keyword:`!match` statement
 ===============================
 
 .. index::
-   ! statement: match
-   ! keyword: case
+   ! pair: statement; match
+   ! pair: keyword; case
    ! single: pattern matching
-   keyword: if
-   keyword: as
+   pair: keyword; if
+   pair: keyword; as
    pair: match; case
    single: as; match statement
    single: : (colon); compound statement
@@ -1101,12 +1101,12 @@ Function definitions
 ====================
 
 .. index::
-   statement: def
+   pair: statement; def
    pair: function; definition
    pair: function; name
    pair: name; binding
-   object: user-defined function
-   object: function
+   pair: object; user-defined function
+   pair: object; function
    pair: function; name
    pair: name; binding
    single: () (parentheses); function definition
@@ -1274,8 +1274,8 @@ Class definitions
 =================
 
 .. index::
-   object: class
-   statement: class
+   pair: object; class
+   pair: statement; class
    pair: class; definition
    pair: class; name
    pair: name; binding
@@ -1374,7 +1374,7 @@ Coroutines
 
 .. versionadded:: 3.5
 
-.. index:: statement: async def
+.. index:: pair: statement; async def
 .. _`async def`:
 
 Coroutine function definition
@@ -1385,8 +1385,8 @@ Coroutine function definition
                 : ["->" `expression`] ":" `suite`
 
 .. index::
-   keyword: async
-   keyword: await
+   pair: keyword; async
+   pair: keyword; await
 
 Execution of Python coroutines can be suspended and resumed at many points
 (see :term:`coroutine`). :keyword:`await` expressions, :keyword:`async for` and
@@ -1408,7 +1408,7 @@ An example of a coroutine function::
    ``await`` and ``async`` are now keywords; previously they were only
    treated as such inside the body of a coroutine function.
 
-.. index:: statement: async for
+.. index:: pair: statement; async for
 .. _`async for`:
 
 The :keyword:`!async for` statement
@@ -1453,7 +1453,7 @@ It is a :exc:`SyntaxError` to use an ``a
 body of a coroutine function.
 
 
-.. index:: statement: async with
+.. index:: pair: statement; async with
 .. _`async with`:
 
 The :keyword:`!async with` statement
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -21,8 +21,8 @@ conformance to Von Neumann's model of a
 represented by objects.)
 
 .. index::
-   builtin: id
-   builtin: type
+   pair: built-in function; id
+   pair: built-in function; type
    single: identity of an object
    single: value of an object
    single: type of an object
@@ -142,7 +142,7 @@ attributes.'  These are attributes that
 are not intended for general use.  Their definition may change in the future.
 
 None
-   .. index:: object: None
+   .. index:: pair: object; None
 
    This type has a single value.  There is a single object with this value. This
    object is accessed through the built-in name ``None``. It is used to signify the
@@ -150,7 +150,7 @@ None
    don't explicitly return anything. Its truth value is false.
 
 NotImplemented
-   .. index:: object: NotImplemented
+   .. index:: pair: object; NotImplemented
 
    This type has a single value.  There is a single object with this value. This
    object is accessed through the built-in name ``NotImplemented``. Numeric methods
@@ -171,7 +171,7 @@ NotImplemented
 
 Ellipsis
    .. index::
-      object: Ellipsis
+      pair: object; Ellipsis
       single: ...; ellipsis literal
 
    This type has a single value.  There is a single object with this value. This
@@ -179,7 +179,7 @@ Ellipsis
    ``Ellipsis``.  Its truth value is true.
 
 :class:`numbers.Number`
-   .. index:: object: numeric
+   .. index:: pair: object; numeric
 
    These are created by numeric literals and returned as results by arithmetic
    operators and arithmetic built-in functions.  Numeric objects are immutable;
@@ -209,7 +209,7 @@ Ellipsis
    numbers:
 
    :class:`numbers.Integral`
-      .. index:: object: integer
+      .. index:: pair: object; integer
 
       These represent elements from the mathematical set of integers (positive and
       negative).
@@ -225,7 +225,7 @@ Ellipsis
 
       Booleans (:class:`bool`)
          .. index::
-            object: Boolean
+            pair: object; Boolean
             single: False
             single: True
 
@@ -242,7 +242,7 @@ Ellipsis
 
    :class:`numbers.Real` (:class:`float`)
       .. index::
-         object: floating point
+         pair: object; floating point
          pair: floating point; number
          pair: C; language
          pair: Java; language
@@ -257,7 +257,7 @@ Ellipsis
 
    :class:`numbers.Complex` (:class:`complex`)
       .. index::
-         object: complex
+         pair: object; complex
          pair: complex; number
 
       These represent complex numbers as a pair of machine-level double precision
@@ -267,8 +267,8 @@ Ellipsis
 
 Sequences
    .. index::
-      builtin: len
-      object: sequence
+      pair: built-in function; len
+      pair: object; sequence
       single: index operation
       single: item selection
       single: subscription
@@ -293,8 +293,8 @@ Sequences
 
    Immutable sequences
       .. index::
-         object: immutable sequence
-         object: immutable
+         pair: object; immutable sequence
+         pair: object; immutable
 
       An object of an immutable sequence type cannot change once it is created.  (If
       the object contains references to other objects, these other objects may be
@@ -308,8 +308,8 @@ Sequences
 
       Strings
          .. index::
-            builtin: chr
-            builtin: ord
+            pair: built-in function; chr
+            pair: built-in function; ord
             single: character
             single: integer
             single: Unicode
@@ -328,7 +328,7 @@ Sequences
 
       Tuples
          .. index::
-            object: tuple
+            pair: object; tuple
             pair: singleton; tuple
             pair: empty; tuple
 
@@ -350,8 +350,8 @@ Sequences
 
    Mutable sequences
       .. index::
-         object: mutable sequence
-         object: mutable
+         pair: object; mutable sequence
+         pair: object; mutable
          pair: assignment; statement
          single: subscription
          single: slicing
@@ -363,7 +363,7 @@ Sequences
       There are currently two intrinsic mutable sequence types:
 
       Lists
-         .. index:: object: list
+         .. index:: pair: object; list
 
          The items of a list are arbitrary Python objects.  Lists are formed by
          placing a comma-separated list of expressions in square brackets. (Note
@@ -377,15 +377,15 @@ Sequences
          (and hence unhashable), byte arrays otherwise provide the same interface
          and functionality as immutable :class:`bytes` objects.
 
-      .. index:: module: array
+      .. index:: pair: module; array
 
       The extension module :mod:`array` provides an additional example of a
       mutable sequence type, as does the :mod:`collections` module.
 
 Set types
    .. index::
-      builtin: len
-      object: set type
+      pair: built-in function; len
+      pair: object; set type
 
    These represent unordered, finite sets of unique, immutable objects. As such,
    they cannot be indexed by any subscript. However, they can be iterated over, and
@@ -402,14 +402,14 @@ Set types
    There are currently two intrinsic set types:
 
    Sets
-      .. index:: object: set
+      .. index:: pair: object; set
 
       These represent a mutable set. They are created by the built-in :func:`set`
       constructor and can be modified afterwards by several methods, such as
       :meth:`~set.add`.
 
    Frozen sets
-      .. index:: object: frozenset
+      .. index:: pair: object; frozenset
 
       These represent an immutable set.  They are created by the built-in
       :func:`frozenset` constructor.  As a frozenset is immutable and
@@ -418,9 +418,9 @@ Set types
 
 Mappings
    .. index::
-      builtin: len
+      pair: built-in function; len
       single: subscription
-      object: mapping
+      pair: object; mapping
 
    These represent finite sets of objects indexed by arbitrary index sets. The
    subscript notation ``a[k]`` selects the item indexed by ``k`` from the mapping
@@ -431,7 +431,7 @@ Mappings
    There is currently a single intrinsic mapping type:
 
    Dictionaries
-      .. index:: object: dictionary
+      .. index:: pair: object; dictionary
 
       These represent finite sets of objects indexed by nearly arbitrary values.  The
       only types of values not acceptable as keys are values containing lists or
@@ -451,8 +451,8 @@ Mappings
       section :ref:`dict`).
 
       .. index::
-         module: dbm.ndbm
-         module: dbm.gnu
+         pair: module; dbm.ndbm
+         pair: module; dbm.gnu
 
       The extension modules :mod:`dbm.ndbm` and :mod:`dbm.gnu` provide
       additional examples of mapping types, as does the :mod:`collections`
@@ -465,7 +465,7 @@ Mappings
 
 Callable types
    .. index::
-      object: callable
+      pair: object; callable
       pair: function; call
       single: invocation
       pair: function; argument
@@ -476,8 +476,8 @@ Callable types
    User-defined functions
       .. index::
          pair: user-defined; function
-         object: function
-         object: user-defined function
+         pair: object; function
+         pair: object; user-defined function
 
       A user-defined function object is created by a function definition (see
       section :ref:`function`).  It should be called with an argument list
@@ -580,8 +580,8 @@ Callable types
 
    Instance methods
       .. index::
-         object: method
-         object: user-defined method
+         pair: object; method
+         pair: object; user-defined method
          pair: user-defined; method
 
       An instance method object combines a class, a class instance and any
@@ -688,8 +688,8 @@ Callable types
 
    Built-in functions
       .. index::
-         object: built-in function
-         object: function
+         pair: object; built-in function
+         pair: object; function
          pair: C; language
 
       A built-in function object is a wrapper around a C function.  Examples of
@@ -703,8 +703,8 @@ Callable types
 
    Built-in methods
       .. index::
-         object: built-in method
-         object: method
+         pair: object; built-in method
+         pair: object; method
          pair: built-in; method
 
       This is really a different disguise of a built-in function, this time containing
@@ -727,8 +727,8 @@ Callable types
 
 Modules
    .. index::
-      statement: import
-      object: module
+      pair: statement; import
+      pair: object; module
 
    Modules are a basic organizational unit of Python code, and are created by
    the :ref:`import system <importsystem>` as invoked either by the
@@ -805,12 +805,12 @@ Custom classes
    .. XXX: Could we add that MRO doc as an appendix to the language ref?
 
    .. index::
-      object: class
-      object: class instance
-      object: instance
+      pair: object; class
+      pair: object; class instance
+      pair: object; instance
       pair: class object; call
       single: container
-      object: dictionary
+      pair: object; dictionary
       pair: class; attribute
 
    When a class attribute reference (for class :class:`C`, say) would yield a
@@ -865,8 +865,8 @@ Custom classes
 
 Class instances
    .. index::
-      object: class instance
-      object: instance
+      pair: object; class instance
+      pair: object; instance
       pair: class; instance
       pair: class instance; attribute
 
@@ -892,9 +892,9 @@ Class instances
    dictionary directly.
 
    .. index::
-      object: numeric
-      object: sequence
-      object: mapping
+      pair: object; numeric
+      pair: object; sequence
+      pair: object; mapping
 
    Class instances can pretend to be numbers, sequences, or mappings if they have
    methods with certain special names.  See section :ref:`specialnames`.
@@ -908,8 +908,8 @@ Class instances
 
 I/O objects (also known as file objects)
    .. index::
-      builtin: open
-      module: io
+      pair: built-in function; open
+      pair: module; io
       single: popen() (in module os)
       single: makefile() (socket method)
       single: sys.stdin
@@ -993,7 +993,7 @@ Internal types
       required stack size; :attr:`co_flags` is an integer encoding a number
       of flags for the interpreter.
 
-      .. index:: object: generator
+      .. index:: pair: object; generator
 
       The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if
       the function uses the ``*arguments`` syntax to accept an arbitrary number of
@@ -1017,7 +1017,7 @@ Internal types
    .. _frame-objects:
 
    Frame objects
-      .. index:: object: frame
+      .. index:: pair: object; frame
 
       Frame objects represent execution frames.  They may occur in traceback objects
       (see below), and are also passed to registered trace functions.
@@ -1080,7 +1080,7 @@ Internal types
 
    Traceback objects
       .. index::
-         object: traceback
+         pair: object; traceback
          pair: stack; trace
          pair: exception; handler
          pair: execution; stack
@@ -1114,7 +1114,7 @@ Internal types
          single: tb_frame (traceback attribute)
          single: tb_lineno (traceback attribute)
          single: tb_lasti (traceback attribute)
-         statement: try
+         pair: statement; try
 
       Special read-only attributes:
       :attr:`tb_frame` points to the execution frame of the current level;
@@ -1140,7 +1140,7 @@ Internal types
          and the ``tb_next`` attribute of existing instances can be updated.
 
    Slice objects
-      .. index:: builtin: slice
+      .. index:: pair: built-in function; slice
 
       Slice objects are used to represent slices for
       :meth:`~object.__getitem__`
@@ -1273,7 +1273,7 @@ Basic customization
    .. index::
       single: destructor
       single: finalizer
-      statement: del
+      pair: statement; del
 
    Called when the instance is about to be destroyed.  This is also called a
    finalizer or (improperly) a destructor.  If a base class has a
@@ -1374,7 +1374,7 @@ Basic customization
 
 .. method:: object.__bytes__(self)
 
-   .. index:: builtin: bytes
+   .. index:: pair: built-in function; bytes
 
    Called by :ref:`bytes <func-bytes>` to compute a byte-string representation
    of an object. This should return a :class:`bytes` object.
@@ -1382,7 +1382,7 @@ Basic customization
    .. index::
       single: string; __format__() (object method)
       pair: string; conversion
-      builtin: print
+      pair: built-in function; print
 
 
 .. method:: object.__format__(self, format_spec)
@@ -1461,8 +1461,8 @@ Basic customization
 .. method:: object.__hash__(self)
 
    .. index::
-      object: dictionary
-      builtin: hash
+      pair: object; dictionary
+      pair: built-in function; hash
 
    Called by built-in function :func:`hash` and for operations on members of
    hashed collections including :class:`set`, :class:`frozenset`, and
@@ -1981,7 +1981,7 @@ Metaclasses
 
 .. index::
    single: metaclass
-   builtin: type
+   pair: built-in function; type
    single: = (equals); class definition
 
 By default, classes are constructed using :func:`type`. The class body is
@@ -2395,7 +2395,7 @@ through the object's keys; for sequences
 .. method:: object.__len__(self)
 
    .. index::
-      builtin: len
+      pair: built-in function; len
       single: __bool__() (object method)
 
    Called to implement the built-in function :func:`len`.  Should return the length
@@ -2424,7 +2424,7 @@ through the object's keys; for sequences
    .. versionadded:: 3.4
 
 
-.. index:: object: slice
+.. index:: pair: object; slice
 
 .. note::
 
@@ -2553,9 +2553,9 @@ left undefined.
             object.__or__(self, other)
 
    .. index::
-      builtin: divmod
-      builtin: pow
-      builtin: pow
+      pair: built-in function; divmod
+      pair: built-in function; pow
+      pair: built-in function; pow
 
    These methods are called to implement the binary arithmetic operations
    (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`,
@@ -2588,8 +2588,8 @@ left undefined.
             object.__ror__(self, other)
 
    .. index::
-      builtin: divmod
-      builtin: pow
+      pair: built-in function; divmod
+      pair: built-in function; pow
 
    These methods are called to implement the binary arithmetic operations
    (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`,
@@ -2600,7 +2600,7 @@ left undefined.
    an instance of a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)``
    is called if ``x.__sub__(y)`` returns *NotImplemented*.
 
-   .. index:: builtin: pow
+   .. index:: pair: built-in function; pow
 
    Note that ternary :func:`pow` will not try calling :meth:`__rpow__` (the
    coercion rules would become too complicated).
@@ -2647,7 +2647,7 @@ left undefined.
             object.__abs__(self)
             object.__invert__(self)
 
-   .. index:: builtin: abs
+   .. index:: pair: built-in function; abs
 
    Called to implement the unary arithmetic operations (``-``, ``+``, :func:`abs`
    and ``~``).
@@ -2658,9 +2658,9 @@ left undefined.
             object.__float__(self)
 
    .. index::
-      builtin: complex
-      builtin: int
-      builtin: float
+      pair: built-in function; complex
+      pair: built-in function; int
+      pair: built-in function; float
 
    Called to implement the built-in functions :func:`complex`,
    :func:`int` and :func:`float`.  Should return a value
@@ -2685,7 +2685,7 @@ left undefined.
             object.__floor__(self)
             object.__ceil__(self)
 
-   .. index:: builtin: round
+   .. index:: pair: built-in function; round
 
    Called to implement the built-in function :func:`round` and :mod:`math`
    functions :func:`~math.trunc`, :func:`~math.floor` and :func:`~math.ceil`.
@@ -2710,7 +2710,7 @@ execution of the block of code.  Context
 used by directly invoking their methods.
 
 .. index::
-   statement: with
+   pair: statement; with
    single: context manager
 
 Typical uses of context managers include saving and restoring various kinds of
--- a/Doc/reference/executionmodel.rst
+++ b/Doc/reference/executionmodel.rst
@@ -151,7 +151,7 @@ to previously bound variables in the nea
 :exc:`SyntaxError` is raised at compile time if the given name does not
 exist in any enclosing function scope.
 
-.. index:: module: __main__
+.. index:: pair: module; __main__
 
 The namespace for a module is automatically created the first time a module is
 imported.  The main module for a script is always called :mod:`__main__`.
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -71,7 +71,7 @@ An identifier occurring as an atom is a
 for lexical definition and section :ref:`naming` for documentation of naming and
 binding.
 
-.. index:: exception: NameError
+.. index:: pair: exception; NameError
 
 When the name is bound to an object, evaluation of the atom yields that object.
 When a name is not bound, an attempt to evaluate it raises a :exc:`NameError`
@@ -240,7 +240,7 @@ List displays
    pair: list; display
    pair: list; comprehensions
    pair: empty; list
-   object: list
+   pair: object; list
    single: [] (square brackets); list expression
    single: , (comma); expression list
 
@@ -265,7 +265,7 @@ Set displays
 .. index::
    pair: set; display
    pair: set; comprehensions
-   object: set
+   pair: object; set
    single: {} (curly brackets); set expression
    single: , (comma); expression list
 
@@ -294,7 +294,7 @@ Dictionary displays
    pair: dictionary; display
    pair: dictionary; comprehensions
    key, datum, key/datum pair
-   object: dictionary
+   pair: object; dictionary
    single: {} (curly brackets); dictionary expression
    single: : (colon); in dictionary expressions
    single: , (comma); in dictionary displays
@@ -356,7 +356,7 @@ Generator expressions
 
 .. index::
    pair: generator; expression
-   object: generator
+   pair: object; generator
    single: () (parentheses); generator expression
 
 A generator expression is a compact generator notation in parentheses:
@@ -410,8 +410,8 @@ Yield expressions
 -----------------
 
 .. index::
-   keyword: yield
-   keyword: from
+   pair: keyword; yield
+   pair: keyword; from
    pair: yield; expression
    pair: generator; function
 
@@ -517,7 +517,7 @@ on the right hand side of an assignment
       The proposal that expanded on :pep:`492` by adding generator capabilities to
       coroutine functions.
 
-.. index:: object: generator
+.. index:: pair: object; generator
 .. _generator-methods:
 
 Generator-iterator methods
@@ -529,7 +529,7 @@ be used to control the execution of a ge
 Note that calling any of the generator methods below when the generator
 is already executing raises a :exc:`ValueError` exception.
 
-.. index:: exception: StopIteration
+.. index:: pair: exception; StopIteration
 
 
 .. method:: generator.__next__()
@@ -579,7 +579,7 @@ is already executing raises a :exc:`Valu
    :attr:`~BaseException.__traceback__` attribute stored in *value* may
    be cleared.
 
-.. index:: exception: GeneratorExit
+.. index:: pair: exception; GeneratorExit
 
 
 .. method:: generator.close()
@@ -691,7 +691,7 @@ of a *finalizer* method see the implemen
 The expression ``yield from <expr>`` is a syntax error when used in an
 asynchronous generator function.
 
-.. index:: object: asynchronous-generator
+.. index:: pair: object; asynchronous-generator
 .. _asynchronous-generator-methods:
 
 Asynchronous generator-iterator methods
@@ -701,7 +701,7 @@ This subsection describes the methods of
 which are used to control the execution of a generator function.
 
 
-.. index:: exception: StopAsyncIteration
+.. index:: pair: exception; StopAsyncIteration
 
 .. coroutinemethod:: agen.__anext__()
 
@@ -748,7 +748,7 @@ which are used to control the execution
    raises a different exception, then when the awaitable is run that exception
    propagates to the caller of the awaitable.
 
-.. index:: exception: GeneratorExit
+.. index:: pair: exception; GeneratorExit
 
 
 .. coroutinemethod:: agen.aclose()
@@ -795,9 +795,9 @@ An attribute reference is a primary foll
    attributeref: `primary` "." `identifier`
 
 .. index::
-   exception: AttributeError
-   object: module
-   object: list
+   pair: exception; AttributeError
+   pair: object; module
+   pair: object; list
 
 The primary must evaluate to an object of a type that supports attribute
 references, which most objects do.  This object is then asked to produce the
@@ -818,12 +818,12 @@ Subscriptions
    single: [] (square brackets); subscription
 
 .. index::
-   object: sequence
-   object: mapping
-   object: string
-   object: tuple
-   object: list
-   object: dictionary
+   pair: object; sequence
+   pair: object; mapping
+   pair: object; string
+   pair: object; tuple
+   pair: object; list
+   pair: object; dictionary
    pair: sequence; item
 
 The subscription of an instance of a :ref:`container class <sequence-types>`
@@ -891,10 +891,10 @@ Slicings
    single: , (comma); slicing
 
 .. index::
-   object: sequence
-   object: string
-   object: tuple
-   object: list
+   pair: object; sequence
+   pair: object; string
+   pair: object; tuple
+   pair: object; list
 
 A slicing selects a range of items in a sequence object (e.g., a string, tuple
 or list).  Slicings may be used as expressions or as targets in assignment or
@@ -935,7 +935,7 @@ substituting ``None`` for missing expres
 
 
 .. index::
-   object: callable
+   pair: object; callable
    single: call
    single: argument; call semantics
    single: () (parentheses); call
@@ -1085,8 +1085,8 @@ a user-defined function:
    .. index::
       pair: function; call
       triple: user-defined; function; call
-      object: user-defined function
-      object: function
+      pair: object; user-defined function
+      pair: object; function
 
    The code block for the function is executed, passing it the argument list.  The
    first thing the code block will do is bind the formal parameters to the
@@ -1100,25 +1100,25 @@ a built-in function or method:
       pair: built-in function; call
       pair: method; call
       pair: built-in method; call
-      object: built-in method
-      object: built-in function
-      object: method
-      object: function
+      pair: object; built-in method
+      pair: object; built-in function
+      pair: object; method
+      pair: object; function
 
    The result is up to the interpreter; see :ref:`built-in-funcs` for the
    descriptions of built-in functions and methods.
 
 a class object:
    .. index::
-      object: class
+      pair: object; class
       pair: class object; call
 
    A new instance of that class is returned.
 
 a class instance method:
    .. index::
-      object: class instance
-      object: instance
+      pair: object; class instance
+      pair: object; instance
       pair: class instance; call
 
    The corresponding user-defined function is called, with an argument list that is
@@ -1134,7 +1134,7 @@ a class instance:
    if that method was called.
 
 
-.. index:: keyword: await
+.. index:: pair: keyword; await
 .. _await:
 
 Await expression
@@ -1156,7 +1156,7 @@ The power operator
 
 .. index::
    pair: power; operation
-   operator: **
+   pair: operator; **
 
 The power operator binds more tightly than unary operators on its left; it binds
 less tightly than unary operators on its right.  The syntax is:
@@ -1217,7 +1217,7 @@ operation can be overridden with the :me
 
 .. index::
    single: inversion
-   operator: ~ (tilde)
+   pair: operator; ~ (tilde)
 
 The unary ``~`` (invert) operator yields the bitwise inversion of its integer
 argument.  The bitwise inversion of ``x`` is defined as ``-(x+1)``.  It only
@@ -1226,7 +1226,7 @@ applies to integral numbers or to custom
 
 
 
-.. index:: exception: TypeError
+.. index:: pair: exception; TypeError
 
 In all three cases, if the argument does not have the proper type, a
 :exc:`TypeError` exception is raised.
@@ -1252,7 +1252,7 @@ operators and one for additive operators
 
 .. index::
    single: multiplication
-   operator: * (asterisk)
+   pair: operator; * (asterisk)
 
 The ``*`` (multiplication) operator yields the product of its arguments.  The
 arguments must either both be numbers, or one argument must be an integer and
@@ -1265,7 +1265,7 @@ This operation can be customized using t
 
 .. index::
    single: matrix multiplication
-   operator: @ (at)
+   pair: operator; @ (at)
 
 The ``@`` (at) operator is intended to be used for matrix multiplication.  No
 builtin Python types implement this operator.
@@ -1273,10 +1273,10 @@ builtin Python types implement this oper
 .. versionadded:: 3.5
 
 .. index::
-   exception: ZeroDivisionError
+   pair: exception; ZeroDivisionError
    single: division
-   operator: / (slash)
-   operator: //
+   pair: operator; / (slash)
+   pair: operator; //
 
 The ``/`` (division) and ``//`` (floor division) operators yield the quotient of
 their arguments.  The numeric arguments are first converted to a common type.
@@ -1290,7 +1290,7 @@ This operation can be customized using t
 
 .. index::
    single: modulo
-   operator: % (percent)
+   pair: operator; % (percent)
 
 The ``%`` (modulo) operator yields the remainder from the division of the first
 argument by the second.  The numeric arguments are first converted to a common
@@ -1348,8 +1348,8 @@ Shifting operations
 
 .. index::
    pair: shifting; operation
-   operator: <<
-   operator: >>
+   pair: operator; <<
+   pair: operator; >>
 
 The shifting operations have lower priority than the arithmetic operations:
 
@@ -1362,7 +1362,7 @@ the left or right by the number of bits
 This operation can be customized using the special :meth:`__lshift__` and
 :meth:`__rshift__` methods.
 
-.. index:: exception: ValueError
+.. index:: pair: exception; ValueError
 
 A right shift by *n* bits is defined as floor division by ``pow(2,n)``.  A left
 shift by *n* bits is defined as multiplication with ``pow(2,n)``.
@@ -1384,7 +1384,7 @@ Each of the three bitwise operations has
 
 .. index::
    pair: bitwise; and
-   operator: & (ampersand)
+   pair: operator; & (ampersand)
 
 The ``&`` operator yields the bitwise AND of its arguments, which must be
 integers or one of them must be a custom object overriding :meth:`__and__` or
@@ -1393,7 +1393,7 @@ integers or one of them must be a custom
 .. index::
    pair: bitwise; xor
    pair: exclusive; or
-   operator: ^ (caret)
+   pair: operator; ^ (caret)
 
 The ``^`` operator yields the bitwise XOR (exclusive OR) of its arguments, which
 must be integers or one of them must be a custom object overriding :meth:`__xor__` or
@@ -1402,7 +1402,7 @@ must be integers or one of them must be
 .. index::
    pair: bitwise; or
    pair: inclusive; or
-   operator: | (vertical bar)
+   pair: operator; | (vertical bar)
 
 The ``|`` operator yields the bitwise (inclusive) OR of its arguments, which
 must be integers or one of them must be a custom object overriding :meth:`__or__` or
@@ -1417,12 +1417,12 @@ Comparisons
 .. index::
    single: comparison
    pair: C; language
-   operator: < (less)
-   operator: > (greater)
-   operator: <=
-   operator: >=
-   operator: ==
-   operator: !=
+   pair: operator; < (less)
+   pair: operator; > (greater)
+   pair: operator; <=
+   pair: operator; >=
+   pair: operator; ==
+   pair: operator; !=
 
 Unlike C, all comparison operations in Python have the same priority, which is
 lower than that of any arithmetic, shifting or bitwise operation.  Also unlike
@@ -1652,17 +1652,17 @@ raises the :exc:`IndexError` exception.
 if :keyword:`in` raised that exception).
 
 .. index::
-   operator: in
-   operator: not in
+   pair: operator; in
+   pair: operator; not in
    pair: membership; test
-   object: sequence
+   pair: object; sequence
 
 The operator :keyword:`not in` is defined to have the inverse truth value of
 :keyword:`in`.
 
 .. index::
-   operator: is
-   operator: is not
+   pair: operator; is
+   pair: operator; is not
    pair: identity; test
 
 
@@ -1702,17 +1702,17 @@ control flow statements, the following v
 other values are interpreted as true.  User-defined objects can customize their
 truth value by providing a :meth:`__bool__` method.
 
-.. index:: operator: not
+.. index:: pair: operator; not
 
 The operator :keyword:`not` yields ``True`` if its argument is false, ``False``
 otherwise.
 
-.. index:: operator: and
+.. index:: pair: operator; and
 
 The expression ``x and y`` first evaluates *x*; if *x* is false, its value is
 returned; otherwise, *y* is evaluated and the resulting value is returned.
 
-.. index:: operator: or
+.. index:: pair: operator; or
 
 The expression ``x or y`` first evaluates *x*; if *x* is true, its value is
 returned; otherwise, *y* is evaluated and the resulting value is returned.
@@ -1837,7 +1837,7 @@ Expression lists
    starred_expression: `expression` | (`starred_item` ",")* [`starred_item`]
    starred_item: `assignment_expression` | "*" `or_expr`
 
-.. index:: object: tuple
+.. index:: pair: object; tuple
 
 Except when part of a list or set display, an expression list
 containing at least one comma yields a tuple.  The length of
--- a/Doc/reference/simple_stmts.rst
+++ b/Doc/reference/simple_stmts.rst
@@ -53,8 +53,8 @@ An expression statement evaluates the ex
 expression).
 
 .. index::
-   builtin: repr
-   object: None
+   pair: built-in function; repr
+   pair: object; None
    pair: string; conversion
    single: output
    pair: standard; output
@@ -76,7 +76,7 @@ Assignment statements
    pair: assignment; statement
    pair: binding; name
    pair: rebinding; name
-   object: mutable
+   pair: object; mutable
    pair: attribute; assignment
 
 Assignment statements are used to (re)bind names to values and to modify
@@ -185,7 +185,7 @@ Assignment of an object to a single targ
 
   .. index::
      pair: subscription; assignment
-     object: mutable
+     pair: object; mutable
 
 * If the target is a subscription: The primary expression in the reference is
   evaluated.  It should yield either a mutable sequence object (such as a list)
@@ -193,8 +193,8 @@ Assignment of an object to a single targ
   evaluated.
 
   .. index::
-     object: sequence
-     object: list
+     pair: object; sequence
+     pair: object; list
 
   If the primary is a mutable sequence object (such as a list), the subscript
   must yield an integer.  If it is negative, the sequence's length is added to
@@ -204,8 +204,8 @@ Assignment of an object to a single targ
   raised (assignment to a subscripted sequence cannot add new items to a list).
 
   .. index::
-     object: mapping
-     object: dictionary
+     pair: object; mapping
+     pair: object; dictionary
 
   If the primary is a mapping object (such as a dictionary), the subscript must
   have a type compatible with the mapping's key type, and the mapping is then
@@ -376,7 +376,7 @@ The :keyword:`!assert` statement
 ================================
 
 .. index::
-   ! statement: assert
+   ! pair: statement; assert
    pair: debugging; assertions
    single: , (comma); expression list
 
@@ -398,7 +398,7 @@ The extended form, ``assert expression1,
 
 .. index::
    single: __debug__
-   exception: AssertionError
+   pair: exception; AssertionError
 
 These equivalences assume that :const:`__debug__` and :exc:`AssertionError` refer to
 the built-in variables with those names.  In the current implementation, the
@@ -419,7 +419,7 @@ The :keyword:`!pass` statement
 ==============================
 
 .. index::
-   statement: pass
+   pair: statement; pass
    pair: null; operation
            pair: null; operation
 
@@ -441,7 +441,7 @@ The :keyword:`!del` statement
 =============================
 
 .. index::
-   ! statement: del
+   ! pair: statement; del
    pair: deletion; target
    triple: deletion; target; list
 
@@ -454,7 +454,7 @@ Rather than spelling it out in full deta
 Deletion of a target list recursively deletes each target, from left to right.
 
 .. index::
-   statement: global
+   pair: statement; global
    pair: unbinding; name
 
 Deletion of a name removes the binding of that name from the local or global
@@ -480,7 +480,7 @@ The :keyword:`!return` statement
 ================================
 
 .. index::
-   ! statement: return
+   ! pair: statement; return
    pair: function; definition
    pair: class; definition
 
@@ -495,7 +495,7 @@ If an expression list is present, it is
 :keyword:`return` leaves the current function call with the expression list (or
 ``None``) as return value.
 
-.. index:: keyword: finally
+.. index:: pair: keyword; finally
 
 When :keyword:`return` passes control out of a :keyword:`try` statement with a
 :keyword:`finally` clause, that :keyword:`!finally` clause is executed before
@@ -517,11 +517,11 @@ The :keyword:`!yield` statement
 ===============================
 
 .. index::
-   statement: yield
+   pair: statement; yield
    single: generator; function
    single: generator; iterator
    single: function; generator
-   exception: StopIteration
+   pair: exception; StopIteration
 
 .. productionlist:: python-grammar
    yield_stmt: `yield_expression`
@@ -553,7 +553,7 @@ The :keyword:`!raise` statement
 ===============================
 
 .. index::
-   ! statement: raise
+   ! pair: statement; raise
    single: exception
    pair: raising; exception
    single: __traceback__ (exception attribute)
@@ -574,7 +574,7 @@ instantiating the class with no argument
 The :dfn:`type` of the exception is the exception instance's class, the
 :dfn:`value` is the instance itself.
 
-.. index:: object: traceback
+.. index:: pair: object; traceback
 
 A traceback object is normally created automatically when an exception is raised
 and attached to it as the :attr:`__traceback__` attribute, which is writable.
@@ -661,9 +661,9 @@ The :keyword:`!break` statement
 ===============================
 
 .. index::
-   ! statement: break
-   statement: for
-   statement: while
+   ! pair: statement; break
+   pair: statement; for
+   pair: statement; while
    pair: loop; statement
 
 .. productionlist:: python-grammar
@@ -673,7 +673,7 @@ The :keyword:`!break` statement
 :keyword:`while` loop, but not nested in a function or class definition within
 that loop.
 
-.. index:: keyword: else
+.. index:: pair: keyword; else
            pair: loop control; target
 
 It terminates the nearest enclosing loop, skipping the optional :keyword:`!else`
@@ -682,7 +682,7 @@ clause if the loop has one.
 If a :keyword:`for` loop is terminated by :keyword:`break`, the loop control
 target keeps its current value.
 
-.. index:: keyword: finally
+.. index:: pair: keyword; finally
 
 When :keyword:`break` passes control out of a :keyword:`try` statement with a
 :keyword:`finally` clause, that :keyword:`!finally` clause is executed before
@@ -695,11 +695,11 @@ The :keyword:`!continue` statement
 ==================================
 
 .. index::
-   ! statement: continue
-   statement: for
-   statement: while
+   ! pair: statement; continue
+   pair: statement; for
+   pair: statement; while
    pair: loop; statement
-   keyword: finally
+   pair: keyword; finally
 
 .. productionlist:: python-grammar
    continue_stmt: "continue"
@@ -720,12 +720,12 @@ The :keyword:`!import` statement
 ================================
 
 .. index::
-   ! statement: import
+   ! pair: statement; import
    single: module; importing
    pair: name; binding
-   keyword: from
-   keyword: as
-   exception: ImportError
+   pair: keyword; from
+   pair: keyword; as
+   pair: exception; ImportError
    single: , (comma); import statement
 
 .. productionlist:: python-grammar
@@ -936,7 +936,7 @@ The :keyword:`!global` statement
 ================================
 
 .. index::
-   ! statement: global
+   ! pair: statement; global
    triple: global; name; binding
    single: , (comma); identifier list
 
@@ -964,9 +964,9 @@ annotation.
    them or silently change the meaning of the program.
 
 .. index::
-   builtin: exec
-   builtin: eval
-   builtin: compile
+   pair: built-in function; exec
+   pair: built-in function; eval
+   pair: built-in function; compile
 
 **Programmer's note:** :keyword:`global` is a directive to the parser.  It
 applies only to code parsed at the same time as the :keyword:`!global` statement.
@@ -982,7 +982,7 @@ call.  The same applies to the :func:`ev
 The :keyword:`!nonlocal` statement
 ==================================
 
-.. index:: statement: nonlocal
+.. index:: pair: statement; nonlocal
    single: , (comma); identifier list
 
 .. productionlist:: python-grammar
--- a/Doc/reference/toplevel_components.rst
+++ b/Doc/reference/toplevel_components.rst
@@ -21,9 +21,9 @@ Complete Python programs
 .. index:: single: program
 
 .. index::
-   module: sys
-   module: __main__
-   module: builtins
+   pair: module; sys
+   pair: module; __main__
+   pair: module; builtins
 
 While a language specification need not prescribe how the language interpreter
 is invoked, it is useful to have a notion of a complete Python program.  A
@@ -38,7 +38,7 @@ the next section.
 
 .. index::
    single: interactive mode
-   module: __main__
+   pair: module; __main__
 
 The interpreter may also be invoked in interactive mode; in this case, it does
 not read and execute a complete program but reads and executes one statement
@@ -98,7 +98,7 @@ Expression input
 ================
 
 .. index:: single: input
-.. index:: builtin: eval
+.. index:: pair: built-in function; eval
 
 :func:`eval` is used for expression input.  It ignores leading whitespace. The
 string argument to :func:`eval` must have the following form:
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -623,6 +623,30 @@ def process_audit_events(app, doctree, f
         node.replace_self(table)
 
 
+def patch_pairindextypes(app) -> None:
+    if app.builder.name != 'gettext':
+        return
+
+    # allow translating deprecated index entries
+    try:
+        from sphinx.domains.python import pairindextypes
+    except ImportError:
+        pass
+    else:
+        # Sphinx checks if a 'pair' type entry on an index directive is one of
+        # the Sphinx-translated pairindextypes values. As we intend to move
+        # away from this, we need Sphinx to believe that these values don't
+        # exist, by deleting them when using the gettext builder.
+
+        pairindextypes.pop('module', None)
+        pairindextypes.pop('keyword', None)
+        pairindextypes.pop('operator', None)
+        pairindextypes.pop('object', None)
+        pairindextypes.pop('exception', None)
+        pairindextypes.pop('statement', None)
+        pairindextypes.pop('builtin', None)
+
+
 def setup(app):
     app.add_role('issue', issue_role)
     app.add_role('gh', gh_issue_role)
@@ -645,6 +669,7 @@ def setup(app):
     app.add_directive_to_domain('py', 'awaitablemethod', PyAwaitableMethod)
     app.add_directive_to_domain('py', 'abstractmethod', PyAbstractMethod)
     app.add_directive('miscnews', MiscNews)
+    app.connect('builder-inited', patch_pairindextypes)
     app.connect('doctree-resolved', process_audit_events)
     app.connect('env-merge-info', audit_events_merge)
     app.connect('env-purge-doc', audit_events_purge)
--- a/Doc/tutorial/classes.rst
+++ b/Doc/tutorial/classes.rst
@@ -344,7 +344,7 @@ list objects have methods called append,
 However, in the following discussion, we'll use the term method exclusively to
 mean methods of class instance objects, unless explicitly stated otherwise.)
 
-.. index:: object: method
+.. index:: pair: object; method
 
 Valid method names of an instance object depend on its class.  By definition,
 all attributes of a class that are function  objects define corresponding
--- a/Doc/tutorial/controlflow.rst
+++ b/Doc/tutorial/controlflow.rst
@@ -46,7 +46,7 @@ details see :ref:`tut-match`.
 ==========================
 
 .. index::
-   statement: for
+   pair: statement; for
 
 The :keyword:`for` statement in Python differs a bit from what you may be used
 to in C or Pascal.  Rather than always iterating over an arithmetic progression
--- a/Doc/tutorial/inputoutput.rst
+++ b/Doc/tutorial/inputoutput.rst
@@ -285,8 +285,8 @@ Reading and Writing Files
 =========================
 
 .. index::
-   builtin: open
-   object: file
+   pair: built-in function; open
+   pair: object; file
 
 :func:`open` returns a :term:`file object`, and is most commonly used with
 two positional arguments and one keyword argument:
@@ -466,7 +466,7 @@ Reference for a complete guide to file o
 Saving structured data with :mod:`json`
 ---------------------------------------
 
-.. index:: module: json
+.. index:: pair: module; json
 
 Strings can easily be written to and read from a file.  Numbers take a bit more
 effort, since the :meth:`read` method only returns strings, which will have to
--- a/Doc/tutorial/modules.rst
+++ b/Doc/tutorial/modules.rst
@@ -260,7 +260,7 @@ Some tips for experts:
 Standard Modules
 ================
 
-.. index:: module: sys
+.. index:: pair: module; sys
 
 Python comes with a library of standard modules, described in a separate
 document, the Python Library Reference ("Library Reference" hereafter).  Some
@@ -341,7 +341,7 @@ Without arguments, :func:`dir` lists the
 
 Note that it lists all types of names: variables, modules, functions, etc.
 
-.. index:: module: builtins
+.. index:: pair: module; builtins
 
 :func:`dir` does not list the names of built-in functions and variables.  If you
 want a list of those, they are defined in the standard module
--- a/Doc/tutorial/stdlib.rst
+++ b/Doc/tutorial/stdlib.rst
@@ -24,7 +24,7 @@ Be sure to use the ``import os`` style i
 will keep :func:`os.open` from shadowing the built-in :func:`open` function which
 operates much differently.
 
-.. index:: builtin: help
+.. index:: pair: built-in function; help
 
 The built-in :func:`dir` and :func:`help` functions are useful as interactive
 aids for working with large modules like :mod:`os`::
openSUSE Build Service is sponsored by