← requests  /  src/requests/_types.py

1
"""
2
requests._types
3
~~~~~~~~~~~~~~~
4
5
This module contains type aliases used internally by the Requests library.
6
These types are not part of the public API and must not be relied upon
7
by external code.
8
"""
9
10
from __future__ import annotations
11
12
from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence
13
from typing import (
14
    TYPE_CHECKING,
15
    Any,
16
    Protocol,
17
    TypeAlias,
18
    TypeVar,
19
    runtime_checkable,
20
)
21
22
_T_co = TypeVar("_T_co", covariant=True)
23
_KT_co = TypeVar("_KT_co", covariant=True)
24
_VT_co = TypeVar("_VT_co", covariant=True)
25
26
27
@runtime_checkable
28
class SupportsRead(Protocol[_T_co]):
29
    def read(self, length: int = ..., /) -> _T_co: ...
30
31
32
@runtime_checkable
33
class SupportsItems(Protocol[_KT_co, _VT_co]):
34
    def items(self) -> Iterable[tuple[_KT_co, _VT_co]]: ...
35
36
37
# These are needed at runtime for default_hooks() return type
38
HookType: TypeAlias = Callable[["Response"], Any]
39
HooksInputType: TypeAlias = Mapping[str, Iterable[HookType] | HookType]
40
41
42
def is_prepared(request: PreparedRequest) -> TypeIs[_ValidatedRequest]:
43
    """Verify a PreparedRequest has been fully prepared."""
44
    if TYPE_CHECKING:
45
        return request.url is not None and request.method is not None
46
    # noop at runtime to avoid AssertionError
47
    return True
48
49
50
if TYPE_CHECKING:
51
    from http.cookiejar import CookieJar
52
    from typing import TypeAlias, TypedDict
53
54
    from typing_extensions import (
55
        Buffer,  # TODO: move to collections.abc when Python >= 3.12
56
        TypeIs,  # TODO: move to typing when Python >= 3.13
57
    )
58
59
    from .auth import AuthBase
60
    from .cookies import RequestsCookieJar
61
    from .models import PreparedRequest, Response
62
    from .structures import CaseInsensitiveDict
63
64
    class _ValidatedRequest(PreparedRequest):
65
        """Subtype asserting a PreparedRequest has been fully prepared before calling.
66
67
        The override suppression is required because mutable attribute types are
68
        invariant (Liskov), but we only narrow after preparation is complete. This
69
        is the explicit contract for Requests but Python's typing doesn't have a
70
        better way to represent the requirement.
71
        """
72
73
        url: str  # type: ignore[reportIncompatibleVariableOverride]
74
        method: str  # type: ignore[reportIncompatibleVariableOverride]
75
76
    # Type aliases for core API concepts (ordered by request() signature)
77
    UriType: TypeAlias = str | bytes
78
79
    _ParamsMappingKeyType: TypeAlias = str | bytes | int | float
80
    _ParamsMappingValueType: TypeAlias = (
81
        str | bytes | int | float | Iterable[str | bytes | int | float] | None
82
    )
83
    ParamsType: TypeAlias = (
84
        SupportsItems[_ParamsMappingKeyType, _ParamsMappingValueType]
85
        | tuple[tuple[_ParamsMappingKeyType, _ParamsMappingValueType], ...]
86
        | Iterable[tuple[_ParamsMappingKeyType, _ParamsMappingValueType]]
87
        | str
88
        | bytes
89
        | None
90
    )
91
92
    KVDataType: TypeAlias = Iterable[tuple[Any, Any]] | SupportsItems[Any, Any]
93
94
    RawDataType: TypeAlias = KVDataType | str | bytes
95
    StreamDataType: TypeAlias = SupportsRead[str | bytes]
96
    EncodableDataType: TypeAlias = RawDataType | StreamDataType
97
98
    DataType: TypeAlias = (
99
        KVDataType
100
        | Iterable[bytes | str]
101
        | str
102
        | bytes
103
        | Buffer
104
        | SupportsRead[str | bytes]
105
        | None
106
    )
107
108
    BodyType: TypeAlias = (
109
        bytes | str | Iterable[bytes | str] | SupportsRead[bytes | str] | None
110
    )
111
112
    HeadersType: TypeAlias = Mapping[str, str | bytes] | None
113
114
    CookiesType: TypeAlias = RequestsCookieJar | Mapping[str, str]
115
116
    # Building blocks for FilesType
117
    _FileName: TypeAlias = str | None
118
    _FileContent: TypeAlias = SupportsRead[str | bytes] | str | bytes
119
    _FileSpecBasic: TypeAlias = tuple[_FileName, _FileContent]
120
    _FileSpecWithContentType: TypeAlias = tuple[_FileName, _FileContent, str]
121
    _FileSpecWithHeaders: TypeAlias = tuple[
122
        _FileName, _FileContent, str, CaseInsensitiveDict[str] | Mapping[str, str]
123
    ]
124
    _FileSpec: TypeAlias = (
125
        _FileContent | _FileSpecBasic | _FileSpecWithContentType | _FileSpecWithHeaders
126
    )
127
    FilesType: TypeAlias = (
128
        Mapping[str, _FileSpec] | Iterable[tuple[str, _FileSpec]] | None
129
    )
130
131
    AuthType: TypeAlias = (
132
        tuple[str, str] | AuthBase | Callable[[PreparedRequest], PreparedRequest] | None
133
    )
134
135
    TimeoutType: TypeAlias = float | tuple[float | None, float | None] | None
136
    ProxiesType: TypeAlias = MutableMapping[str, str]
137
    HooksType: TypeAlias = dict[str, list[HookType]] | None
138
    VerifyType: TypeAlias = bool | str
139
    CertType: TypeAlias = str | tuple[str, str] | None
140
    JsonType: TypeAlias = (
141
        None
142
        | bool
143
        | int
144
        | float
145
        | str
146
        | Sequence["JsonType"]
147
        | Mapping[str, "JsonType"]
148
    )
149
150
    # TypedDicts for Unpack kwargs (PEP 692)
151
152
    class BaseRequestKwargs(TypedDict, total=False):
153
        headers: HeadersType
154
        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
155
        files: FilesType
156
        auth: AuthType
157
        timeout: TimeoutType
158
        allow_redirects: bool
159
        proxies: dict[str, str] | None
160
        hooks: HooksInputType | None
161
        stream: bool | None
162
        verify: VerifyType | None
163
        cert: CertType
164
165
    class RequestKwargs(BaseRequestKwargs, total=False):
166
        """kwargs for request(), options(), head(), delete()."""
167
168
        params: ParamsType
169
        data: DataType
170
        json: JsonType
171
172
    class GetKwargs(BaseRequestKwargs, total=False):
173
        data: DataType
174
        json: JsonType
175
176
    class PostKwargs(BaseRequestKwargs, total=False):
177
        params: ParamsType
178
179
    class DataKwargs(BaseRequestKwargs, total=False):
180
        """kwargs for put(), patch()."""
181
182
        params: ParamsType
183
        json: JsonType
184