-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Add inline types to Requests #7272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
412bc3d
781caba
b686e75
5204ac3
541fb87
4a6d321
5c93c71
f651c9b
09d56f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| name: Type Check | ||
|
|
||
| on: [push, pull_request] | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| typecheck: | ||
| runs-on: ubuntu-24.04 | ||
| timeout-minutes: 10 | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | ||
| with: | ||
| python-version: "3.10" | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| python -m pip install pip==26.0.1 | ||
| python -m pip install -e . --group typecheck | ||
|
|
||
| - name: Run pyright | ||
| run: python -m pyright src/requests/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| """ | ||
| requests._types | ||
| ~~~~~~~~~~~~~~~ | ||
|
|
||
| This module contains type aliases used internally by the Requests library. | ||
| These types are not part of the public API and must not be relied upon | ||
| by external code. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from collections.abc import Callable, Iterable, Mapping, MutableMapping | ||
| from typing import ( | ||
| TYPE_CHECKING, | ||
| Any, | ||
| Protocol, | ||
| TypeVar, | ||
| runtime_checkable, | ||
| ) | ||
|
|
||
| _T_co = TypeVar("_T_co", covariant=True) | ||
|
|
||
|
|
||
| @runtime_checkable | ||
| class SupportsRead(Protocol[_T_co]): | ||
| def read(self, length: int = ...) -> _T_co: ... | ||
nateprewitt marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| @runtime_checkable | ||
| class SupportsItems(Protocol): | ||
| def items(self) -> Iterable[tuple[Any, Any]]: ... | ||
|
|
||
|
|
||
| # These are needed at runtime for default_hooks() return type | ||
| HookType = Callable[["Response"], Any] | ||
| HooksInputType = Mapping[str, "Iterable[HookType] | HookType"] | ||
nateprewitt marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def is_prepared(request: PreparedRequest) -> TypeIs[_ValidatedRequest]: | ||
| """Verify a PreparedRequest has been fully prepared.""" | ||
| if TYPE_CHECKING: | ||
| return request.url is not None and request.method is not None | ||
| # noop at runtime to avoid AssertionError | ||
| return True | ||
|
|
||
|
|
||
| if TYPE_CHECKING: | ||
| from typing import TypeAlias | ||
|
|
||
| from typing_extensions import TypeIs # move to typing when Python >= 3.13 | ||
|
|
||
| from .auth import AuthBase | ||
| from .cookies import RequestsCookieJar | ||
| from .models import PreparedRequest, Response | ||
| from .structures import CaseInsensitiveDict | ||
|
|
||
| class _ValidatedRequest(PreparedRequest): | ||
| """Subtype asserting a PreparedRequest has been fully prepared before calling. | ||
|
|
||
| The override suppression is required because mutable attribute types are | ||
| invariant (Liskov), but we only narrow after preparation is complete. This | ||
| is the explicit contract for Requests but Python's typing doesn't have a | ||
| better way to represent the requirement. | ||
| """ | ||
|
|
||
| url: str # type: ignore[reportIncompatibleVariableOverride] | ||
| method: str # type: ignore[reportIncompatibleVariableOverride] | ||
|
|
||
| # Type aliases for core API concepts (ordered by request() signature) | ||
| UriType: TypeAlias = str | bytes | ||
|
|
||
| _ParamsMappingKeyType: TypeAlias = str | bytes | int | float | ||
| _ParamsMappingValueType: TypeAlias = ( | ||
| str | bytes | int | float | Iterable[str | bytes | int | float] | None | ||
| ) | ||
| ParamsType: TypeAlias = ( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it would be lovely if these type hints were available through a "public" interface, since I've often written code that wraps a requests call, where I would want to use the ParamsType to annotate my own code I say public in quotes because I could import this, but it feels wrong
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree having some form of public hints for the top-level APIs is potentially warranted. I started very conservative here because often times new code goes into Requests and immediately comes someone else's critical dependency. I don't want to create a binding contract that people start surfacing in their code, and then "break" when we need to update/tweak it. I think once we're really happy with the types, the main argument parameters could be surfaced. I've deferred that for now until we can make a more informed decision. Presumably everything calling in is already typed sufficiently. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fair! thank you for doing this and considering carefully :) |
||
| Mapping[_ParamsMappingKeyType, _ParamsMappingValueType] | ||
| | tuple[tuple[_ParamsMappingKeyType, _ParamsMappingValueType], ...] | ||
| | Iterable[tuple[_ParamsMappingKeyType, _ParamsMappingValueType]] | ||
| | str | ||
| | bytes | ||
| | None | ||
| ) | ||
|
|
||
| KVDataType: TypeAlias = Iterable[tuple[Any, Any]] | Mapping[Any, Any] | ||
|
|
||
| EncodableDataType: TypeAlias = KVDataType | str | bytes | SupportsRead[str | bytes] | ||
|
|
||
| DataType: TypeAlias = ( | ||
| KVDataType | ||
| | Iterable[bytes | str] | ||
| | str | ||
| | bytes | ||
| | SupportsRead[str | bytes] | ||
| | None | ||
| ) | ||
|
|
||
| BodyType: TypeAlias = ( | ||
| bytes | str | Iterable[bytes | str] | SupportsRead[bytes | str] | None | ||
| ) | ||
|
|
||
| HeadersType: TypeAlias = CaseInsensitiveDict[str] | Mapping[str, str | bytes] | ||
| HeadersUpdateType: TypeAlias = Mapping[str, str | bytes | None] | ||
|
|
||
| CookiesType: TypeAlias = RequestsCookieJar | Mapping[str, str] | ||
|
|
||
| # Building blocks for FilesType | ||
| _FileName: TypeAlias = str | None | ||
| _FileContent: TypeAlias = SupportsRead[str | bytes] | str | bytes | ||
| _FileSpecBasic: TypeAlias = tuple[_FileName, _FileContent] | ||
| _FileSpecWithContentType: TypeAlias = tuple[_FileName, _FileContent, str] | ||
| _FileSpecWithHeaders: TypeAlias = tuple[ | ||
| _FileName, _FileContent, str, CaseInsensitiveDict[str] | Mapping[str, str] | ||
| ] | ||
| _FileSpec: TypeAlias = ( | ||
| _FileContent | _FileSpecBasic | _FileSpecWithContentType | _FileSpecWithHeaders | ||
| ) | ||
| FilesType: TypeAlias = ( | ||
| Mapping[str, _FileSpec] | Iterable[tuple[str, _FileSpec]] | None | ||
| ) | ||
|
|
||
| AuthType: TypeAlias = ( | ||
| tuple[str, str] | AuthBase | Callable[[PreparedRequest], PreparedRequest] | None | ||
| ) | ||
|
|
||
| TimeoutType: TypeAlias = float | tuple[float | None, float | None] | None | ||
| ProxiesType: TypeAlias = MutableMapping[str, str] | ||
| HooksType: TypeAlias = dict[str, list["HookType"]] | None | ||
nateprewitt marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| VerifyType: TypeAlias = bool | str | ||
| CertType: TypeAlias = str | tuple[str, str] | None | ||
| JsonType: TypeAlias = ( | ||
| None | bool | int | float | str | list["JsonType"] | dict[str, "JsonType"] | ||
| ) | ||
Uh oh!
There was an error while loading. Please reload this page.