File support-python-311.patch of Package python-Sphinx

Index: sphinx-9.1.0/pyproject.toml
===================================================================
--- sphinx-9.1.0.orig/pyproject.toml
+++ sphinx-9.1.0/pyproject.toml
@@ -17,7 +17,7 @@ license = "BSD-2-Clause"
 license-files = [
     "LICENSE.rst",
 ]
-requires-python = ">=3.12"
+requires-python = ">=3.11"
 
 # Classifiers list: https://pypi.org/classifiers/
 classifiers = [
Index: sphinx-9.1.0/sphinx/_cli/__init__.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/_cli/__init__.py
+++ sphinx-9.1.0/sphinx/_cli/__init__.py
@@ -36,10 +36,12 @@ from sphinx.locale import __, init_conso
 
 if TYPE_CHECKING:
     from collections.abc import Callable, Iterable, Iterator, Sequence
-    from typing import NoReturn
+    from typing import NoReturn, TypeAlias
 
-    type _PARSER_SETUP = Callable[[argparse.ArgumentParser], argparse.ArgumentParser]
-    type _RUNNER = Callable[[argparse.Namespace], int]
+    _PARSER_SETUP: TypeAlias = Callable[
+        [argparse.ArgumentParser], argparse.ArgumentParser
+    ]
+    _RUNNER: TypeAlias = Callable[[argparse.Namespace], int]
 
     from typing import Protocol
 
Index: sphinx-9.1.0/sphinx/builders/html/__init__.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/builders/html/__init__.py
+++ sphinx-9.1.0/sphinx/builders/html/__init__.py
@@ -64,7 +64,7 @@ from sphinx.writers.html5 import HTML5Tr
 
 if TYPE_CHECKING:
     from collections.abc import Iterator, Set
-    from typing import Any
+    from typing import Any, TypeAlias
 
     from docutils.nodes import Node
 
@@ -79,7 +79,7 @@ INVENTORY_FILENAME = 'objects.inv'
 logger = logging.getLogger(__name__)
 return_codes_re = re.compile('[\r\n]+')
 
-type DOMAIN_INDEX_TYPE = tuple[
+DOMAIN_INDEX_TYPE: TypeAlias = tuple[
     # Index name (e.g. py-modindex)
     str,
     # Index class
Index: sphinx-9.1.0/sphinx/builders/linkcheck.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/builders/linkcheck.py
+++ sphinx-9.1.0/sphinx/builders/linkcheck.py
@@ -35,7 +35,7 @@ from sphinx.util.nodes import NodeMatche
 
 if TYPE_CHECKING:
     from collections.abc import Callable, Iterator, Sequence
-    from typing import Any, Literal
+    from typing import Any, Literal, TypeAlias
 
     from requests import Response
 
@@ -44,7 +44,7 @@ if TYPE_CHECKING:
     from sphinx.util._pathlib import _StrPath
     from sphinx.util.typing import ExtensionMetadata
 
-    type _URIProperties = tuple[_Status, str, int]
+    _URIProperties: TypeAlias = tuple[_Status, str, int]
 
 
 class _Status(StrEnum):
Index: sphinx-9.1.0/sphinx/config.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/config.py
+++ sphinx-9.1.0/sphinx/config.py
@@ -17,6 +17,7 @@ from sphinx.util import logging
 if TYPE_CHECKING:
     import os
     from collections.abc import Collection, Iterable, Iterator, Sequence, Set
+    from typing import TypeAlias
 
     from sphinx.application import Sphinx
     from sphinx.environment import BuildEnvironment
@@ -25,7 +26,7 @@ if TYPE_CHECKING:
 
 logger = logging.getLogger(__name__)
 
-type _ConfigRebuild = Literal[
+_ConfigRebuild: TypeAlias = Literal[
     '',
     'env',
     'epub',
@@ -91,7 +92,7 @@ class ENUM:
         return all(item in self._candidates for item in value)
 
 
-type _OptValidTypes = frozenset[type] | ENUM
+_OptValidTypes: TypeAlias = frozenset[type] | ENUM
 
 
 class _Opt:
Index: sphinx-9.1.0/sphinx/domains/c/_ast.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/domains/c/_ast.py
+++ sphinx-9.1.0/sphinx/domains/c/_ast.py
@@ -2,7 +2,7 @@ from __future__ import annotations
 
 import sys
 import warnings
-from typing import TYPE_CHECKING, cast
+from typing import TYPE_CHECKING, Union, cast
 
 from docutils import nodes
 
@@ -16,7 +16,7 @@ from sphinx.util.cfamily import (
 )
 
 if TYPE_CHECKING:
-    from typing import Any
+    from typing import Any, TypeAlias
 
     from docutils.nodes import Element, Node, TextElement
 
@@ -27,15 +27,15 @@ if TYPE_CHECKING:
         StringifyTransform,
     )
 
-type DeclarationType = (
-    'ASTStruct'
-    | 'ASTUnion'
-    | 'ASTEnum'
-    | 'ASTEnumerator'
-    | 'ASTType'
-    | 'ASTTypeWithInit'
-    | 'ASTMacro'
-)
+DeclarationType: TypeAlias = Union[
+    'ASTStruct',
+    'ASTUnion',
+    'ASTEnum',
+    'ASTEnumerator',
+    'ASTType',
+    'ASTTypeWithInit',
+    'ASTMacro',
+]
 
 
 class ASTBase(ASTBaseBase):
Index: sphinx-9.1.0/sphinx/environment/adapters/indexentries.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/environment/adapters/indexentries.py
+++ sphinx-9.1.0/sphinx/environment/adapters/indexentries.py
@@ -13,27 +13,27 @@ from sphinx.util import logging
 from sphinx.util.index_entries import _split_into
 
 if TYPE_CHECKING:
-    from typing import Literal
+    from typing import Literal, TypeAlias
 
     from sphinx.builders import Builder
     from sphinx.environment import BuildEnvironment
 
-    type _IndexEntryTarget = tuple[str | None, str | Literal[False]]
-    type _IndexEntryTargets = list[_IndexEntryTarget]
-    type _IndexEntryCategoryKey = str | None
-    type _IndexEntrySubItems = dict[
+    _IndexEntryTarget: TypeAlias = tuple[str | None, str | Literal[False]]
+    _IndexEntryTargets: TypeAlias = list[_IndexEntryTarget]
+    _IndexEntryCategoryKey: TypeAlias = str | None
+    _IndexEntrySubItems: TypeAlias = dict[
         str,
         tuple[_IndexEntryTargets, _IndexEntryCategoryKey],
     ]
-    type _IndexEntry = tuple[
+    _IndexEntry: TypeAlias = tuple[
         _IndexEntryTargets,
         _IndexEntrySubItems,
         _IndexEntryCategoryKey,
     ]
-    type _IndexEntryMap = dict[str, _IndexEntry]
+    _IndexEntryMap: TypeAlias = dict[str, _IndexEntry]
 
     # Used by ``create_index()`` for 'the real index'
-    type _RealIndexEntry = tuple[
+    _RealIndexEntry: TypeAlias = tuple[
         str,
         tuple[
             _IndexEntryTargets,
@@ -41,8 +41,8 @@ if TYPE_CHECKING:
             _IndexEntryCategoryKey,
         ],
     ]
-    type _RealIndexEntries = list[_RealIndexEntry]
-    type _Index = list[tuple[str, _RealIndexEntries]]
+    _RealIndexEntries: TypeAlias = list[_RealIndexEntry]
+    _Index: TypeAlias = list[tuple[str, _RealIndexEntries]]
 
 logger = logging.getLogger(__name__)
 
Index: sphinx-9.1.0/sphinx/ext/autodoc/_dynamic/_signatures.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/ext/autodoc/_dynamic/_signatures.py
+++ sphinx-9.1.0/sphinx/ext/autodoc/_dynamic/_signatures.py
@@ -27,14 +27,14 @@ from sphinx.util.inspect import (
 
 if TYPE_CHECKING:
     from collections.abc import Callable, Mapping
-    from typing import Any
+    from typing import Any, TypeAlias
 
     from sphinx.events import EventManager
     from sphinx.ext.autodoc._directive_options import _AutoDocumenterOptions
     from sphinx.ext.autodoc._property_types import _ItemProperties
     from sphinx.ext.autodoc._shared import _AttrGetter, _AutodocConfig
 
-    type _FormattedSignature = tuple[str, str]
+    _FormattedSignature: TypeAlias = tuple[str, str]
 
 
 def _format_signatures(
Index: sphinx-9.1.0/sphinx/ext/autodoc/_property_types.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/ext/autodoc/_property_types.py
+++ sphinx-9.1.0/sphinx/ext/autodoc/_property_types.py
@@ -8,7 +8,7 @@ TYPE_CHECKING = False
 if TYPE_CHECKING:
     from collections.abc import Sequence
     from pathlib import Path
-    from typing import Any, Literal
+    from typing import Any, Literal, TypeAlias
 
     from sphinx.ext.autodoc._sentinels import (
         RUNTIME_INSTANCE_ATTRIBUTE_T,
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
         UNINITIALIZED_ATTR_T,
     )
 
-    type _AutodocObjType = Literal[
+    _AutodocObjType: TypeAlias = Literal[
         'module',
         'class',
         'exception',
@@ -28,7 +28,7 @@ if TYPE_CHECKING:
         'data',
         'type',
     ]
-    type _AutodocFuncProperty = Literal[
+    _AutodocFuncProperty: TypeAlias = Literal[
         'abstractmethod',
         'async',
         'classmethod',
Index: sphinx-9.1.0/sphinx/ext/autodoc/_sentinels.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/ext/autodoc/_sentinels.py
+++ sphinx-9.1.0/sphinx/ext/autodoc/_sentinels.py
@@ -2,7 +2,7 @@ from __future__ import annotations
 
 TYPE_CHECKING = False
 if TYPE_CHECKING:
-    from typing import Final, Literal, NoReturn, Self, _SpecialForm
+    from typing import Final, Literal, NoReturn, Self, TypeAlias, _SpecialForm
 
 
 class _Sentinel:
@@ -65,14 +65,14 @@ if TYPE_CHECKING:
 
         def __contains__(self, item: object) -> Literal[True]: return True
         def __add__(self, other: object) -> Self: pass
-    type ALL_T = Literal[_AllTC.ALL]
+    ALL_T: TypeAlias = Literal[_AllTC.ALL]
     ALL: Final[ALL_T] = _AllTC.ALL
 
     class _EmptyTC(enum.Enum):
         EMPTY = enum.auto()
 
         def __contains__(self, item: object) -> Literal[False]: return False
-    type EMPTY_T = Literal[_EmptyTC.EMPTY]
+    EMPTY_T: TypeAlias = Literal[_EmptyTC.EMPTY]
     EMPTY: Final[EMPTY_T] = _EmptyTC.EMPTY
 
     class _SentinelTC(enum.Enum):
@@ -81,13 +81,13 @@ if TYPE_CHECKING:
         SLOTS_ATTR = enum.auto()
         SUPPRESS = enum.auto()
         UNINITIALIZED_ATTR = enum.auto()
-    type INSTANCE_ATTR_T = Literal[_SentinelTC.INSTANCE_ATTR]
-    type RUNTIME_INSTANCE_ATTRIBUTE_T = Literal[
+    INSTANCE_ATTR_T: TypeAlias = Literal[_SentinelTC.INSTANCE_ATTR]
+    RUNTIME_INSTANCE_ATTRIBUTE_T: TypeAlias = Literal[
         _SentinelTC.RUNTIME_INSTANCE_ATTRIBUTE
     ]
-    type SLOTS_ATTR_T = Literal[_SentinelTC.SLOTS_ATTR]
-    type SUPPRESS_T = Literal[_SentinelTC.SUPPRESS]
-    type UNINITIALIZED_ATTR_T = Literal[_SentinelTC.UNINITIALIZED_ATTR]
+    SLOTS_ATTR_T: TypeAlias = Literal[_SentinelTC.SLOTS_ATTR]
+    SUPPRESS_T: TypeAlias = Literal[_SentinelTC.SUPPRESS]
+    UNINITIALIZED_ATTR_T: TypeAlias = Literal[_SentinelTC.UNINITIALIZED_ATTR]
     INSTANCE_ATTR: Final[INSTANCE_ATTR_T] = _SentinelTC.INSTANCE_ATTR
     RUNTIME_INSTANCE_ATTRIBUTE: Final[RUNTIME_INSTANCE_ATTRIBUTE_T] = (
         _SentinelTC.RUNTIME_INSTANCE_ATTRIBUTE
Index: sphinx-9.1.0/sphinx/ext/intersphinx/_shared.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/ext/intersphinx/_shared.py
+++ sphinx-9.1.0/sphinx/ext/intersphinx/_shared.py
@@ -8,7 +8,7 @@ from sphinx.util import logging
 
 if TYPE_CHECKING:
     from collections.abc import Sequence
-    from typing import Any, Final, NoReturn
+    from typing import Any, Final, NoReturn, TypeAlias
 
     from sphinx.environment import BuildEnvironment
     from sphinx.util.typing import Inventory
@@ -30,7 +30,7 @@ if TYPE_CHECKING:
     InventoryLocation = str | None
 
     #: Inventory cache entry. The integer field is the cache expiration time.
-    type InventoryCacheEntry = tuple[InventoryName, int, Inventory]
+    InventoryCacheEntry: TypeAlias = tuple[InventoryName, int, Inventory]
 
     #: The type of :confval:`intersphinx_mapping` *after* normalisation.
     IntersphinxMapping = dict[
Index: sphinx-9.1.0/sphinx/pycode/parser.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/pycode/parser.py
+++ sphinx-9.1.0/sphinx/pycode/parser.py
@@ -9,6 +9,7 @@ import inspect
 import itertools
 import operator
 import re
+import sys
 import tokenize
 from token import DEDENT, INDENT, NAME, NEWLINE, NUMBER, OP, STRING
 from tokenize import COMMENT, NL
@@ -20,8 +21,12 @@ if TYPE_CHECKING:
     from inspect import Signature
     from typing import Any
 
-AssignmentLike = ast.Assign | ast.AnnAssign | ast.TypeAlias
-AssignmentLikeType = (ast.Assign, ast.AnnAssign, ast.TypeAlias)
+if sys.version_info[:2] >= (3, 12):
+    AssignmentLike = ast.Assign | ast.AnnAssign | ast.TypeAlias
+    AssignmentLikeType = (ast.Assign, ast.AnnAssign, ast.TypeAlias)
+else:
+    AssignmentLike = ast.Assign | ast.AnnAssign
+    AssignmentLikeType = (ast.Assign, ast.AnnAssign)
 
 comment_re = re.compile('^\\s*#: ?(.*)\r?\n?$')
 indent_re = re.compile('^\\s*$')
Index: sphinx-9.1.0/sphinx/registry.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/registry.py
+++ sphinx-9.1.0/sphinx/registry.py
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
     import os
     from collections.abc import Callable, Iterator, Mapping, Sequence
     from pathlib import Path
-    from typing import Any
+    from typing import Any, TypeAlias
 
     from docutils import nodes
     from docutils.nodes import Element, Node, TextElement
@@ -50,13 +50,13 @@ if TYPE_CHECKING:
     # visit/depart function
     # the parameters should be (SphinxTranslator, Element)
     # or any subtype of either, but mypy rejects this.
-    type _NodeHandler = Callable[[Any, Any], None]
-    type _NodeHandlerPair = tuple[_NodeHandler, _NodeHandler | None]
+    _NodeHandler: TypeAlias = Callable[[Any, Any], None]
+    _NodeHandlerPair: TypeAlias = tuple[_NodeHandler, _NodeHandler | None]
 
-    type _MathsRenderer = Callable[[HTML5Translator, nodes.math], None]
-    type _MathsBlockRenderer = Callable[[HTML5Translator, nodes.math_block], None]
-    type _MathsInlineRenderers = tuple[_MathsRenderer, _MathsRenderer | None]
-    type _MathsBlockRenderers = tuple[_MathsBlockRenderer, _MathsBlockRenderer | None]
+    _MathsRenderer: TypeAlias = Callable[[HTML5Translator, nodes.math], None]
+    _MathsBlockRenderer: TypeAlias = Callable[[HTML5Translator, nodes.math_block], None]
+    _MathsInlineRenderers: TypeAlias = tuple[_MathsRenderer, _MathsRenderer | None]
+    _MathsBlockRenderers: TypeAlias = tuple[_MathsBlockRenderer, _MathsBlockRenderer | None]
 
 logger = logging.getLogger(__name__)
 
Index: sphinx-9.1.0/sphinx/transforms/__init__.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/transforms/__init__.py
+++ sphinx-9.1.0/sphinx/transforms/__init__.py
@@ -23,7 +23,7 @@ from sphinx.util.nodes import apply_sour
 
 if TYPE_CHECKING:
     from collections.abc import Iterable, Iterator
-    from typing import Any, ClassVar, Literal
+    from typing import Any, ClassVar, Literal, TypeAlias
 
     from docutils.nodes import Node
     from typing_extensions import TypeIs
@@ -34,7 +34,7 @@ if TYPE_CHECKING:
     from sphinx.environment import BuildEnvironment
     from sphinx.util.typing import ExtensionMetadata
 
-    type _DEFAULT_SUBSTITUTION_NAMES = Literal[
+    _DEFAULT_SUBSTITUTION_NAMES: TypeAlias = Literal[
         'version',
         'release',
         'today',
Index: sphinx-9.1.0/sphinx/util/cfamily.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/cfamily.py
+++ sphinx-9.1.0/sphinx/util/cfamily.py
@@ -13,13 +13,13 @@ from sphinx.util import logging
 
 if TYPE_CHECKING:
     from collections.abc import Callable, Sequence
-    from typing import Any, NoReturn
+    from typing import Any, NoReturn, TypeAlias
 
     from docutils.nodes import TextElement
 
     from sphinx.config import Config
 
-    type StringifyTransform = Callable[[Any], str]
+    StringifyTransform: TypeAlias = Callable[[Any], str]
 
 logger = logging.getLogger(__name__)
 
Index: sphinx-9.1.0/sphinx/util/docfields.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/docfields.py
+++ sphinx-9.1.0/sphinx/util/docfields.py
@@ -17,6 +17,8 @@ from sphinx.util import logging
 from sphinx.util.nodes import get_node_line
 
 if TYPE_CHECKING:
+    from typing import TypeAlias, TypeVar
+
     from docutils.nodes import Element, Node
     from docutils.parsers.rst.states import Inliner
 
@@ -24,9 +26,10 @@ if TYPE_CHECKING:
     from sphinx.environment import BuildEnvironment
     from sphinx.util.typing import TextlikeNode
 
-    type _FieldEntry = tuple[str, list[Node]]
-    type _FieldTypes = dict[str, list[Node]]
-    type _EntriesTriple = tuple[Field, _FieldEntry | list[_FieldEntry], Element]
+    ObjDescT = TypeVar('ObjDescT')
+    _FieldEntry: TypeAlias = tuple[str, list[Node]]
+    _FieldTypes: TypeAlias = dict[str, list[Node]]
+    _EntriesTriple: TypeAlias = tuple[Field, _FieldEntry | list[_FieldEntry], Element]
 
 logger = logging.getLogger(__name__)
 
@@ -339,7 +342,7 @@ class TypedField(GroupedField):
         return nodes.field('', fieldname, fieldbody)
 
 
-class DocFieldTransformer[ObjDescT]:
+class DocFieldTransformer:
     """Transforms field lists in "doc field" syntax into better-looking
     equivalents, using the field type definitions given on a domain.
     """
Index: sphinx-9.1.0/sphinx/util/i18n.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/i18n.py
+++ sphinx-9.1.0/sphinx/util/i18n.py
@@ -21,7 +21,7 @@ from sphinx.util.osutil import SEP, _las
 if TYPE_CHECKING:
     import datetime as dt
     from collections.abc import Iterator
-    from typing import Protocol
+    from typing import Protocol, TypeAlias
 
     from babel.core import Locale
 
@@ -53,7 +53,7 @@ if TYPE_CHECKING:
             locale: str | Locale | None = ...,
         ) -> str: ...
 
-    type Formatter = DateFormatter | TimeFormatter | DatetimeFormatter
+    Formatter: TypeAlias = DateFormatter | TimeFormatter | DatetimeFormatter
 
 from datetime import UTC
 
Index: sphinx-9.1.0/sphinx/util/inspect.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/inspect.py
+++ sphinx-9.1.0/sphinx/util/inspect.py
@@ -27,7 +27,7 @@ if TYPE_CHECKING:
     from collections.abc import Callable, Iterator, Sequence
     from inspect import _ParameterKind
     from types import MethodType, ModuleType
-    from typing import Final, Protocol
+    from typing import Final, Protocol, TypeAlias
 
     from typing_extensions import TypeIs
 
@@ -47,7 +47,7 @@ if TYPE_CHECKING:
     class _AttrGetter(Protocol):
         def __call__(self, obj: Any, name: str, default: Any = ..., /) -> Any: ...
 
-    type _RoutineType = (
+    _RoutineType: TypeAlias = (
         types.FunctionType
         | types.LambdaType
         | types.MethodType
@@ -57,7 +57,7 @@ if TYPE_CHECKING:
         | types.MethodDescriptorType
         | types.ClassMethodDescriptorType
     )
-    type _SignatureType = (
+    _SignatureType: TypeAlias = (
         Callable[..., Any] | staticmethod[Any, Any] | classmethod[Any, Any, Any]
     )
 
Index: sphinx-9.1.0/sphinx/util/typing.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/typing.py
+++ sphinx-9.1.0/sphinx/util/typing.py
@@ -7,7 +7,7 @@ import sys
 import types
 import typing
 from collections.abc import Callable, Sequence
-from typing import TYPE_CHECKING, TypeAliasType
+from typing import TYPE_CHECKING
 
 from docutils import nodes
 from docutils.parsers.rst.states import Inliner
@@ -16,24 +16,28 @@ from sphinx.util import logging
 
 if TYPE_CHECKING:
     from collections.abc import Mapping
-    from typing import Annotated, Any, Final, Literal, Protocol
+    from typing import Annotated, Any, Final, Literal, Protocol, TypeAlias
 
     from typing_extensions import TypeIs
 
     from sphinx.application import Sphinx
     from sphinx.util.inventory import _InventoryItem
 
-    type _RestifyMode = Literal[
+    _RestifyMode: TypeAlias = Literal[
         'fully-qualified-except-typing',
         'smart',
     ]
-    type _StringifyMode = Literal[
+    _StringifyMode: TypeAlias = Literal[
         'fully-qualified-except-typing',
         'fully-qualified',
         'smart',
     ]
 
-AnyTypeAliasType: tuple[type, ...] = (TypeAliasType,)
+AnyTypeAliasType: tuple[type, ...] = ()
+if sys.version_info[:2] >= (3, 12):
+    from typing import TypeAliasType
+
+    AnyTypeAliasType += (TypeAliasType,)
 
 try:
     import typing_extensions
@@ -125,10 +129,10 @@ def is_invalid_builtin_class(obj: Any) -
 
 
 # Text like nodes which are initialized with text and rawsource
-type TextlikeNode = nodes.Text | nodes.TextElement
+TextlikeNode: TypeAlias = nodes.Text | nodes.TextElement
 
 # path matcher
-type PathMatcher = Callable[[str], bool]
+PathMatcher: TypeAlias = Callable[[str], bool]
 
 # common role functions
 if TYPE_CHECKING:
@@ -147,19 +151,19 @@ if TYPE_CHECKING:
         ) -> tuple[list[nodes.Node], list[nodes.system_message]]: ...
 
 else:
-    type RoleFunction = Callable[
+    RoleFunction: TypeAlias = Callable[
         [str, str, str, int, Inliner, dict[str, typing.Any], Sequence[str]],
         tuple[list[nodes.Node], list[nodes.system_message]],
     ]
 
 # A option spec for directive
-type OptionSpec = dict[str, Callable[[str], typing.Any]]
+OptionSpec: TypeAlias = dict[str, Callable[[str], typing.Any]]
 
 # title getter functions for enumerable nodes (see sphinx.domains.std)
-type TitleGetter = Callable[[nodes.Node], str]
+TitleGetter: TypeAlias = Callable[[nodes.Node], str]
 
 # inventory data on memory
-type Inventory = dict[str, dict[str, _InventoryItem]]
+Inventory: TypeAlias = dict[str, dict[str, '_InventoryItem']]
 
 
 class ExtensionMetadata(typing.TypedDict, total=False):
@@ -183,7 +187,7 @@ class ExtensionMetadata(typing.TypedDict
 
 
 if TYPE_CHECKING:
-    type _ExtensionSetupFunc = Callable[[Sphinx], ExtensionMetadata]  # NoQA: PYI047 (false positive)
+    _ExtensionSetupFunc: TypeAlias = Callable[[Sphinx], ExtensionMetadata]  # NoQA: PYI047 (false positive)
 
 
 def get_type_hints(
@@ -300,6 +304,9 @@ def restify(cls: Any, mode: _RestifyMode
                 else:
                     meta_args.append(repr(m))
             meta = ', '.join(meta_args)
+            if sys.version_info[:2] <= (3, 11):
+                # Hardcoded to fix errors on Python 3.11 and earlier.
+                return rf':py:class:`~typing.Annotated`\ [{args}, {meta}]'
             return (
                 f':py:class:`{module_prefix}{cls.__module__}.{cls.__name__}`'
                 rf'\ [{args}, {meta}]'
@@ -596,6 +603,11 @@ def stringify_annotation(
                 else:
                     meta_args.append(repr(m))
             meta = ', '.join(meta_args)
+            if sys.version_info[:2] <= (3, 11):
+                if mode == 'fully-qualified-except-typing':
+                    return f'Annotated[{args}, {meta}]'
+                module_prefix = module_prefix.replace('builtins', 'typing')
+                return f'{module_prefix}Annotated[{args}, {meta}]'
             return f'{module_prefix}Annotated[{args}, {meta}]'
         elif all(is_system_TypeVar(a) for a in annotation_args):
             # Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT])
Index: sphinx-9.1.0/tests/test_config/test_config.py
===================================================================
--- sphinx-9.1.0.orig/tests/test_config/test_config.py
+++ sphinx-9.1.0/tests/test_config/test_config.py
@@ -23,9 +23,10 @@ from sphinx.util.tags import Tags
 if TYPE_CHECKING:
     from collections.abc import Iterable
     from pathlib import Path
+    from typing import TypeAlias
 
-    type CircularList = list[int | 'CircularList']
-    type CircularDict = dict[str, int | 'CircularDict']
+    CircularList: TypeAlias = list[int | 'CircularList']
+    CircularDict: TypeAlias = dict[str, int | 'CircularDict']
 
 
 def check_is_serializable(subject: object, *, circular: bool) -> None:
Index: sphinx-9.1.0/sphinx/environment/adapters/toctree.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/environment/adapters/toctree.py
+++ sphinx-9.1.0/sphinx/environment/adapters/toctree.py
@@ -3,7 +3,7 @@
 from __future__ import annotations
 
 import warnings
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, TypeVar
 
 from docutils import nodes
 from docutils.nodes import Element
@@ -482,9 +482,12 @@ def _toctree_add_classes(node: Element,
                     subnode = subnode.parent
 
 
-def _toctree_copy[ET: Element](
-    node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
-) -> ET:
+_ET = TypeVar('_ET', bound=Element)
+
+
+def _toctree_copy(
+    node: _ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
+) -> _ET:
     """Utility: Cut and deep-copy a TOC at a specified depth."""
     assert not isinstance(node, addnodes.only)
     depth = max(depth - 1, 1)
Index: sphinx-9.1.0/sphinx/util/nodes.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/nodes.py
+++ sphinx-9.1.0/sphinx/util/nodes.py
@@ -6,7 +6,7 @@ import contextlib
 import re
 import unicodedata
 from io import StringIO
-from typing import TYPE_CHECKING, Any, cast
+from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
 
 from docutils import nodes
 from docutils.nodes import Node
@@ -36,7 +36,10 @@ explicit_title_re = re.compile(r'^(.+?)\
 caption_ref_re = explicit_title_re  # b/w compat alias
 
 
-class NodeMatcher[N: Node]:
+N = TypeVar('N', bound=Node)
+
+
+class NodeMatcher(Generic[N]):
     """A helper class for Node.findall().
 
     It checks that the given node is an instance of the specified node-classes and
Index: sphinx-9.1.0/sphinx/util/docutils.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/docutils.py
+++ sphinx-9.1.0/sphinx/util/docutils.py
@@ -35,7 +35,7 @@ report_re = re.compile(
 if TYPE_CHECKING:
     from collections.abc import Iterator, Mapping, Sequence
     from types import ModuleType, TracebackType
-    from typing import Any, Protocol
+    from typing import Any, Protocol, TypeAlias
 
     from docutils import Component
     from docutils.nodes import Element, Node, system_message
@@ -50,7 +50,7 @@ if TYPE_CHECKING:
     from sphinx.events import EventManager
     from sphinx.util.typing import RoleFunction
 
-    type _DocutilsSettings = docutils.frontend.Values  # pyright: ignore[reportDeprecated]  # ty: ignore[deprecated]
+    _DocutilsSettings: TypeAlias = docutils.frontend.Values  # pyright: ignore[reportDeprecated]  # ty: ignore[deprecated]
 
     class _LanguageModule(Protocol):
         labels: dict[str, str]
Index: sphinx-9.1.0/sphinx/directives/__init__.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/directives/__init__.py
+++ sphinx-9.1.0/sphinx/directives/__init__.py
@@ -3,7 +3,7 @@
 from __future__ import annotations
 
 import re
-from typing import TYPE_CHECKING, cast
+from typing import TYPE_CHECKING, Generic, TypeVar, cast
 
 from docutils import nodes
 from docutils.parsers.rst import directives, roles
@@ -41,7 +41,10 @@ def optional_int(argument: str) -> int |
         return value
 
 
-class ObjectDescription[ObjDescT](SphinxDirective):
+ObjDescT = TypeVar('ObjDescT')
+
+
+class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
     """Directive to describe a class, function or similar object.
 
     Not used directly, but subclassed (in domain-specific directives)
Index: sphinx-9.1.0/sphinx/util/display.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/display.py
+++ sphinx-9.1.0/sphinx/util/display.py
@@ -10,7 +10,11 @@ TYPE_CHECKING = False
 if TYPE_CHECKING:
     from collections.abc import Callable, Iterable, Iterator
     from types import TracebackType
-    from typing import Any
+    from typing import Any, ParamSpec, TypeVar
+
+    T = TypeVar('T')
+    P = ParamSpec('P')
+    R = TypeVar('R')
 
 logger = logging.getLogger(__name__)
 
@@ -23,7 +27,7 @@ def display_chunk(chunk: Any) -> str:
     return str(chunk)
 
 
-def status_iterator[T](
+def status_iterator(
     iterable: Iterable[T],
     summary: str,
     color: str = 'darkgreen',
@@ -86,7 +90,7 @@ class progress_message:
 
         return False
 
-    def __call__[**P, R](self, f: Callable[P, R]) -> Callable[P, R]:
+    def __call__(self, f: Callable[P, R]) -> Callable[P, R]:
         @functools.wraps(f)
         def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:  # type: ignore[return]
             with self:
Index: sphinx-9.1.0/sphinx/search/__init__.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/search/__init__.py
+++ sphinx-9.1.0/sphinx/search/__init__.py
@@ -21,18 +21,21 @@ from sphinx.util.index_entries import sp
 
 if TYPE_CHECKING:
     from collections.abc import Callable, Iterable, Set
-    from typing import Any, Protocol
+    from typing import Any, Protocol, TypeVar
 
     from docutils.nodes import Node
 
     from sphinx.environment import BuildEnvironment
 
-    class _ReadableStream[T](Protocol):
-        def read(self, n: int = ..., /) -> T: ...
-        def readline(self, n: int = ..., /) -> T: ...
+    _T_co = TypeVar('_T_co', covariant=True)
+    _T_contra = TypeVar('_T_contra', contravariant=True)
 
-    class _WritableStream[T](Protocol):
-        def write(self, s: T, /) -> object: ...
+    class _ReadableStream(Protocol[_T_co]):
+        def read(self, n: int = ..., /) -> _T_co: ...
+        def readline(self, n: int = ..., /) -> _T_co: ...
+
+    class _WritableStream(Protocol[_T_contra]):
+        def write(self, s: _T_contra, /) -> object: ...
 
 
 _NON_MINIFIED_JS_PATH = package_dir.joinpath('search', 'non-minified-js')
Index: sphinx-9.1.0/sphinx/transforms/i18n.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/transforms/i18n.py
+++ sphinx-9.1.0/sphinx/transforms/i18n.py
@@ -5,7 +5,7 @@ from __future__ import annotations
 from operator import attrgetter
 from re import DOTALL, match
 from textwrap import indent
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING, Any, TypeVar
 
 import docutils.utils
 from docutils import nodes
@@ -48,6 +48,9 @@ logger = logging.getLogger(__name__)
 EXCLUDED_PENDING_XREF_ATTRIBUTES = ('refexplicit',)
 
 
+N = TypeVar('N', bound=nodes.Node)
+
+
 def _publish_msgstr(
     source: str,
     source_path: str,
@@ -228,7 +231,7 @@ class _NodeUpdater:
 
     def update_autofootnote_references(self) -> None:
         # auto-numbered foot note reference should use original 'ids'.
-        def list_replace_or_append[N: nodes.Node](lst: list[N], old: N, new: N) -> None:
+        def list_replace_or_append(lst: list[N], old: N, new: N) -> None:
             if old in lst:
                 lst[lst.index(old)] = new
             else:
Index: sphinx-9.1.0/sphinx/util/osutil.py
===================================================================
--- sphinx-9.1.0.orig/sphinx/util/osutil.py
+++ sphinx-9.1.0/sphinx/util/osutil.py
@@ -186,6 +186,8 @@ def _relative_path(path: Path, root: Pat
     if path.anchor != root.anchor or '..' in root.parts:
         # If the drives are different, no relative path exists.
         return path
+    if sys.version_info[:2] < (3, 12):
+        return Path(os.path.relpath(path, root))
     return path.relative_to(root, walk_up=True)
 
 
Index: sphinx-9.1.0/tests/test_ext_napoleon/test_ext_napoleon.py
===================================================================
--- sphinx-9.1.0.orig/tests/test_ext_napoleon/test_ext_napoleon.py
+++ sphinx-9.1.0/tests/test_ext_napoleon/test_ext_napoleon.py
@@ -14,15 +14,19 @@ from sphinx.ext.napoleon import Config,
 TYPE_CHECKING = False
 if TYPE_CHECKING:
     from collections.abc import Callable
+    from typing import ParamSpec, TypeVar
 
     from sphinx.ext.autodoc._property_types import _AutodocObjType
 
+    _P = ParamSpec('_P')
+    _R = TypeVar('_R')
 
-def simple_decorator[**P, R](f: Callable[P, R]) -> Callable[P, R]:
+
+def simple_decorator(f: Callable[_P, _R]) -> Callable[_P, _R]:
     """A simple decorator that does nothing, for tests to use."""
 
     @functools.wraps(f)
-    def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
+    def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
         return f(*args, **kwargs)
 
     return wrapper
Index: sphinx-9.1.0/tests/test_directives/test_directives_no_typesetting.py
===================================================================
--- sphinx-9.1.0.orig/tests/test_directives/test_directives_no_typesetting.py
+++ sphinx-9.1.0/tests/test_directives/test_directives_no_typesetting.py
@@ -11,9 +11,11 @@ from sphinx.testing.util import assert_n
 
 TYPE_CHECKING = False
 if TYPE_CHECKING:
+    from typing import TypeAlias
+
     from sphinx.testing.util import SphinxTestApp
 
-    type _IndexEntry = tuple[str, str, str, str, str | None]
+    _IndexEntry: TypeAlias = tuple[str, str, str, str, str | None]
 
 DOMAINS = [
     # directive, no-index, no-index-entry, signature of f, signature of g, index entry of g
Index: sphinx-9.1.0/tests/test_ext_autodoc/test_ext_autodoc.py
===================================================================
--- sphinx-9.1.0.orig/tests/test_ext_autodoc/test_ext_autodoc.py
+++ sphinx-9.1.0/tests/test_ext_autodoc/test_ext_autodoc.py
@@ -1420,10 +1420,12 @@ class _EnumFormatter:
                 )
             else:
                 return '(*values)'
-        return (
-            '(value, names=None, *values, module=None, '
-            'qualname=None, type=None, start=1, boundary=None)'
-        )
+        if sys.version_info[:2] >= (3, 12):
+            return (
+                '(value, names=None, *values, module=None, '
+                'qualname=None, type=None, start=1, boundary=None)'
+            )
+        return '(value)'
 
     def method(
         self,
@@ -2204,6 +2206,10 @@ def test_autodoc_GenericAlias() -> None:
     ]
 
 
+@pytest.mark.skipif(
+    sys.version_info[:2] < (3, 12),
+    reason='type statement introduced in Python 3.12',
+)
 def test_autodoc_pep695_type_alias() -> None:
     config = _AutodocConfig(
         autodoc_type_aliases={
Index: sphinx-9.1.0/tests/test_ext_autodoc/test_ext_autodoc_signatures.py
===================================================================
--- sphinx-9.1.0.orig/tests/test_ext_autodoc/test_ext_autodoc_signatures.py
+++ sphinx-9.1.0/tests/test_ext_autodoc/test_ext_autodoc_signatures.py
@@ -2,6 +2,7 @@
 
 from __future__ import annotations
 
+import sys
 from typing import Generic, TypeVar
 
 import pytest
@@ -119,6 +120,10 @@ def test_format_function_signatures() ->
     assert format_sig('function', 'g', g) == (r"(a='\n')", '')
 
 
+@pytest.mark.skipif(
+    sys.version_info[:2] < (3, 12),
+    reason='type statement introduced in Python 3.12',
+)
 @pytest.mark.parametrize(
     ('params', 'expect'),
     [
Index: sphinx-9.1.0/tests/test_util/test_util_typing.py
===================================================================
--- sphinx-9.1.0.orig/tests/test_util/test_util_typing.py
+++ sphinx-9.1.0/tests/test_util/test_util_typing.py
@@ -198,10 +198,13 @@ def test_is_invalid_builtin_class() -> N
         WrapperDescriptorType,
         # weakref
         WeakSet,
-        # zipfile
-        zipfile.Path,
-        zipfile.CompleteDirs,
     )
+    if sys.version_info[:2] >= (3, 12):
+        invalid_types += (
+            # zipfile
+            zipfile.Path,
+            zipfile.CompleteDirs,
+        )
     if sys.version_info[:2] == (3, 13):
         invalid_types += (
             # pathlib
@@ -223,6 +226,11 @@ def test_is_invalid_builtin_class() -> N
             ('pathlib._local', 'PureWindowsPath'),
             ('pathlib._local', 'WindowsPath'),
         }
+    if sys.version_info[:2] < (3, 12):
+        invalid_names |= {
+            ('zipfile._path', 'Path'),
+            ('zipfile._path', 'CompleteDirs'),
+        }
     assert set(_INVALID_BUILTIN_CLASSES) == invalid_names
 
 
@@ -480,9 +488,14 @@ def test_restify_Unpack() -> None:
         label: str
 
     # Unpack is considered as typing special form so we always have '~'
-    expect = r':py:obj:`~typing.Unpack`\ [:py:class:`X`]'
-    assert restify(UnpackCompat['X'], 'fully-qualified-except-typing') == expect
-    assert restify(UnpackCompat['X'], 'smart') == expect
+    if sys.version_info[:2] >= (3, 12):
+        expect = r':py:obj:`~typing.Unpack`\ [:py:class:`X`]'
+        assert restify(UnpackCompat['X'], 'fully-qualified-except-typing') == expect
+        assert restify(UnpackCompat['X'], 'smart') == expect
+    else:
+        expect = r':py:obj:`~typing_extensions.Unpack`\ [:py:class:`X`]'
+        assert restify(UnpackCompat['X'], 'fully-qualified-except-typing') == expect
+        assert restify(UnpackCompat['X'], 'smart') == expect
 
     expect = r':py:obj:`~typing.Unpack`\ [:py:class:`X`]'
     assert restify(t.Unpack['X'], 'fully-qualified-except-typing') == expect
Index: sphinx-9.1.0/tests/test_ext_autodoc/test_ext_autodoc_configs.py
===================================================================
--- sphinx-9.1.0.orig/tests/test_ext_autodoc/test_ext_autodoc_configs.py
+++ sphinx-9.1.0/tests/test_ext_autodoc/test_ext_autodoc_configs.py
@@ -858,7 +858,7 @@ def test_autodoc_type_aliases() -> None:
 
 
 def test_autodoc_default_options() -> None:
-    if sys.version_info[:3] >= (3, 12, 1):
+    if (3, 11, 7) <= sys.version_info < (3, 12) or sys.version_info >= (3, 12, 1):
         list_of_weak_references = '      list of weak references to the object'
     else:
         list_of_weak_references = '      list of weak references to the object (if defined)'  # fmt: skip
@@ -935,7 +935,7 @@ def test_autodoc_default_options() -> No
 
 
 def test_autodoc_default_options_with_values() -> None:
-    if sys.version_info[:3] >= (3, 12, 1):
+    if (3, 11, 7) <= sys.version_info < (3, 12) or sys.version_info >= (3, 12, 1):
         list_of_weak_references = '      list of weak references to the object'
     else:
         list_of_weak_references = '      list of weak references to the object (if defined)'  # fmt: skip
openSUSE Build Service is sponsored by