[3.11] GH-97950: Use new-style index directive ('module') (GH-103996) (#104154)

diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 087e0a6..092e548 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -543,7 +543,7 @@
 .. c:function:: int PyErr_CheckSignals()
 
    .. index::
-      module: signal
+      pair: module; signal
       single: SIGINT
       single: KeyboardInterrupt (built-in exception)
 
@@ -574,7 +574,7 @@
 .. c:function:: void PyErr_SetInterrupt()
 
    .. index::
-      module: signal
+      pair: module; signal
       single: SIGINT
       single: KeyboardInterrupt (built-in exception)
 
@@ -589,7 +589,7 @@
 .. 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
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 615708e..dda87f4 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -233,9 +233,9 @@
       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()
@@ -942,7 +942,7 @@
 
    .. deprecated:: 3.9
 
-   .. index:: module: _thread
+   .. index:: pair: module; _thread
 
 
 .. c:function:: int PyEval_ThreadsInitialized()
@@ -1385,9 +1385,9 @@
 .. 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)
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index a8f9e9b..bd37ed5 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -705,9 +705,9 @@
 
 .. 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)
 
diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst
index ecd7a68..3d7e354 100644
--- a/Doc/library/_thread.rst
+++ b/Doc/library/_thread.rst
@@ -206,7 +206,7 @@
 
 **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`
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 5a0815f..21960cb 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -6,8 +6,8 @@
               representations.
 
 .. index::
-   module: uu
-   module: base64
+   pair: module; uu
+   pair: module; base64
 
 --------------
 
diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst
index 5ed7a09..b17d58e 100644
--- a/Doc/library/cmath.rst
+++ b/Doc/library/cmath.rst
@@ -301,7 +301,7 @@
    .. 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
diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst
index a8bc2fa..8f32477 100644
--- a/Doc/library/copy.rst
+++ b/Doc/library/copy.rst
@@ -68,7 +68,7 @@
 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
diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst
index afc3e66..2a28c04 100644
--- 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
 
 --------------
 
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index 18c3f47..aee1cb5 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -318,7 +318,7 @@
 .. 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"
diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst
index 46bf0fc..aed8991 100644
--- 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 @@
 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
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 1c3deb2..53294aa 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -1339,7 +1339,7 @@
       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`,
@@ -1979,7 +1979,7 @@
 
    .. index::
       statement: import
-      module: imp
+      pair: module; builtins
 
    .. note::
 
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
index bf0bf0f..9aeb07f 100644
--- 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
 
 --------------
 
diff --git a/Doc/library/internet.rst b/Doc/library/internet.rst
index ff58dcf..681769a 100644
--- a/Doc/library/internet.rst
+++ b/Doc/library/internet.rst
@@ -9,7 +9,7 @@
    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
diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst
index 0614930..2948105 100644
--- a/Doc/library/locale.rst
+++ b/Doc/library/locale.rst
@@ -16,7 +16,7 @@
 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.
@@ -476,7 +476,7 @@
 
 .. 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
diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst
index 24f9dc1..0556f19 100644
--- a/Doc/library/marshal.rst
+++ b/Doc/library/marshal.rst
@@ -15,8 +15,8 @@
 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
diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst
index 22d07c4..1a6b121 100644
--- a/Doc/library/os.path.rst
+++ b/Doc/library/os.path.rst
@@ -159,7 +159,7 @@
    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
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index 19e5bee..b4812e2 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -1185,7 +1185,7 @@
 
 .. 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
@@ -2707,7 +2707,7 @@
    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::
 
diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst
index a556fcc..8798155 100644
--- a/Doc/library/pdb.rst
+++ b/Doc/library/pdb.rst
@@ -20,8 +20,8 @@
 
 .. 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
diff --git a/Doc/library/posix.rst b/Doc/library/posix.rst
index ec04b0d..0413f9d 100644
--- a/Doc/library/posix.rst
+++ b/Doc/library/posix.rst
@@ -11,7 +11,7 @@
 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`
diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst
index 98f3c45..7cafc66 100644
--- a/Doc/library/pwd.rst
+++ b/Doc/library/pwd.rst
@@ -39,7 +39,7 @@
 
 .. 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
diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst
index d6581e2..935e872 100644
--- a/Doc/library/pyexpat.rst
+++ b/Doc/library/pyexpat.rst
@@ -33,7 +33,7 @@
 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.
diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst
index 26a4f14..e161458 100644
--- a/Doc/library/runpy.rst
+++ b/Doc/library/runpy.rst
@@ -30,7 +30,7 @@
 .. 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 @@
 .. 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
diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst
index a50fc6f..dc87af3 100644
--- 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
 
 --------------
 
@@ -95,8 +95,8 @@
 ------------
 
   .. 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
diff --git a/Doc/library/site.rst b/Doc/library/site.rst
index 5941739..34b38f4 100644
--- a/Doc/library/site.rst
+++ b/Doc/library/site.rst
@@ -109,7 +109,7 @@
 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 @@
 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
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index d1b5a1c..e222dc7 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -1829,7 +1829,7 @@
 .. 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
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index e7d43b2..2199829 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -330,7 +330,7 @@
 
 (3)
    .. index::
-      module: math
+      pair: module; math
       single: floor() (in module math)
       single: ceil() (in module math)
       single: trunc() (in module math)
@@ -1561,7 +1561,7 @@
 --------------
 
 .. index::
-   module: re
+   pair: module; re
 
 Strings implement all of the :ref:`common <typesseq-common>` sequence
 operations, along with the additional methods described below.
@@ -2467,7 +2467,7 @@
    object: bytes
    object: bytearray
    object: memoryview
-   module: array
+   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
@@ -5325,7 +5325,7 @@
 
 .. index::
    builtin: type
-   module: types
+   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
diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst
index 54228b8..ade59db 100644
--- a/Doc/reference/compound_stmts.rst
+++ b/Doc/reference/compound_stmts.rst
@@ -297,7 +297,7 @@
 keeping all locals in that frame alive until the next garbage collection occurs.
 
 .. index::
-   module: sys
+   pair: module; sys
    object: traceback
 
 Before an :keyword:`!except` clause's suite is executed,
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 277b9e5..e8117d9 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -377,7 +377,7 @@
          (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.
@@ -451,8 +451,8 @@
       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`
@@ -909,7 +909,7 @@
 I/O objects (also known as file objects)
    .. index::
       builtin: open
-      module: io
+      pair: module; io
       single: popen() (in module os)
       single: makefile() (socket method)
       single: sys.stdin
diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst
index a264015..8917243 100644
--- a/Doc/reference/executionmodel.rst
+++ b/Doc/reference/executionmodel.rst
@@ -151,7 +151,7 @@
 :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__`.
diff --git a/Doc/reference/toplevel_components.rst b/Doc/reference/toplevel_components.rst
index 319c9de..ee472ac 100644
--- a/Doc/reference/toplevel_components.rst
+++ b/Doc/reference/toplevel_components.rst
@@ -21,9 +21,9 @@
 .. 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 @@
 
 .. 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
diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py
index 3ff2a91..1888428 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -694,7 +694,7 @@ def patch_pairindextypes(app) -> None:
         # 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('module', None)
         # pairindextypes.pop('keyword', None)
         # pairindextypes.pop('operator', None)
         # pairindextypes.pop('object', None)
@@ -702,10 +702,6 @@ def patch_pairindextypes(app) -> None:
         # pairindextypes.pop('statement', None)
         # pairindextypes.pop('builtin', None)
 
-        # there needs to be at least one statement in this block, will be
-        # removed when the first of the below is uncommented.
-        pass
-
 
 def setup(app):
     app.add_role('issue', issue_role)
diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst
index 3581b37..aeacc15 100644
--- a/Doc/tutorial/inputoutput.rst
+++ b/Doc/tutorial/inputoutput.rst
@@ -466,7 +466,7 @@
 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
diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst
index 4daafa4..3bd034b 100644
--- a/Doc/tutorial/modules.rst
+++ b/Doc/tutorial/modules.rst
@@ -264,7 +264,7 @@
 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
@@ -345,7 +345,7 @@
 
 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