Skip to content

Commit 158fd4f

Browse files
authored
Introduce flake8-pyi in pre-commit checks (#286)
This is a PR similar to typeddjango/django-stubs#1253, only for rest_framework-stubs. All statements that are unclear on how to proceed are marked with # noqa: in the code, with the exception of compat.pyi, which has additional rules turned off in setup.cfg. * configure flake8-pyi plugin in pre-commit * fix Y015 * fix Y037 * use PEP 585 container types where possible, replace obsolete typing types with collections.abc * disable Y041 rule * add typealias annotation where feasible, add self annotations * fix failing tests, silence remaining warnings since unclear how to proceed * address review * amend tests * amend rebase error Signed-off-by: Oleg Hoefling <[email protected]>
1 parent a1ec425 commit 158fd4f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1073
-1123
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ repos:
2727
rev: 5.0.4
2828
hooks:
2929
- id: flake8
30+
additional_dependencies:
31+
- flake8-pyi==22.10.0
32+
types: []
33+
files: ^.*.pyi?$
3034
- repo: local
3135
hooks:
3236
- id: mypy
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Optional, Tuple, Type
1+
from typing import Any
22

33
from django.contrib.auth import authenticate as authenticate
44
from django.db.models import Model
@@ -10,23 +10,23 @@ def get_authorization_header(request: Request) -> bytes: ...
1010
class CSRFCheck(CsrfViewMiddleware): ...
1111

1212
class BaseAuthentication:
13-
def authenticate(self, request: Request) -> Optional[Tuple[Any, Any]]: ...
14-
def authenticate_header(self, request: Request) -> Optional[str]: ...
13+
def authenticate(self, request: Request) -> tuple[Any, Any] | None: ... # noqa: F811
14+
def authenticate_header(self, request: Request) -> str | None: ...
1515

1616
class BasicAuthentication(BaseAuthentication):
17-
www_authenticate_realm: str = ...
17+
www_authenticate_realm: str
1818
def authenticate_credentials(
19-
self, userid: str, password: str, request: Optional[Request] = ...
20-
) -> Tuple[Any, None]: ...
19+
self, userid: str, password: str, request: Request | None = ...
20+
) -> tuple[Any, None]: ...
2121

2222
class SessionAuthentication(BaseAuthentication):
2323
def enforce_csrf(self, request: Request) -> None: ...
2424

2525
class TokenAuthentication(BaseAuthentication):
26-
keyword: str = ...
27-
model: Optional[Type[Model]] = ...
28-
def get_model(self) -> Type[Model]: ...
29-
def authenticate_credentials(self, key: str) -> Tuple[Any, Any]: ...
26+
keyword: str
27+
model: type[Model] | None
28+
def get_model(self) -> type[Model]: ...
29+
def authenticate_credentials(self, key: str) -> tuple[Any, Any]: ...
3030

3131
class RemoteUserAuthentication(BaseAuthentication):
32-
header: str = ...
32+
header: str
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
default_app_config: str = ...
1+
default_app_config: str

rest_framework-stubs/authtoken/management/commands/drf_create_token.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ from django.core.management.base import BaseCommand
66
UserModel: AbstractBaseUser
77

88
class Command(BaseCommand):
9-
help: str = ...
9+
help: str
1010
def create_user_token(self, username: str, reset_token: bool): ...
1111
def add_arguments(self, parser: Any) -> None: ...
1212
def handle(self, *args: Any, **options: Any) -> None: ...

rest_framework-stubs/authtoken/models.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ from typing import Any
33
from django.db import models
44

55
class Token(models.Model):
6-
key: models.CharField = ...
7-
user: models.OneToOneField = ...
8-
created: models.DateTimeField = ...
6+
key: models.CharField
7+
user: models.OneToOneField
8+
created: models.DateTimeField
99
@classmethod
1010
def generate_key(cls) -> str: ...
1111

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from rest_framework import serializers
22

33
class AuthTokenSerializer(serializers.Serializer):
4-
username: serializers.CharField = ...
5-
password: serializers.CharField = ...
6-
token: serializers.CharField = ...
4+
username: serializers.CharField
5+
password: serializers.CharField
6+
token: serializers.CharField
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
from typing import Any, Type
1+
from typing import Any
22

33
from rest_framework.request import Request
44
from rest_framework.response import Response
55
from rest_framework.serializers import Serializer
66
from rest_framework.views import APIView, AsView, GenericView
77

88
class ObtainAuthToken(APIView):
9-
serializer_class: Type[Serializer] = ...
9+
serializer_class: type[Serializer]
1010
def post(self, request: Request, *args: Any, **kwargs: Any) -> Response: ...
1111

12-
obtain_auth_token: AsView[GenericView] = ...
12+
obtain_auth_token: AsView[GenericView]

rest_framework-stubs/checks.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from typing import Any, List
1+
from typing import Any
22

3-
def pagination_system_check(app_configs: Any, **kwargs: Any) -> List[Any]: ...
3+
def pagination_system_check(app_configs: Any, **kwargs: Any) -> list[Any]: ...

rest_framework-stubs/compat.pyi

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Optional, Tuple, Union
1+
from typing import Any
22

33
import requests # noqa: F401
44
from django.db.models import QuerySet
@@ -43,19 +43,19 @@ if markdown is not None and pygments is not None:
4343
from markdown.preprocessors import Preprocessor # type: ignore
4444

4545
class CodeBlockPreprocessor(Preprocessor):
46-
pattern: Any = ...
47-
formatter: Any = ...
46+
pattern: Any
47+
formatter: Any
4848
def run(self, lines: Any): ...
4949

50-
def pygments_css(style: Any) -> Optional[str]: ...
50+
def pygments_css(style: Any) -> str | None: ...
5151
def pygments_highlight(text: str, lang: str, style: Any) -> Any: ...
5252
def md_filter_add_syntax_highlight(md: Any) -> bool: ...
53-
def unicode_http_header(value: Union[str, bytes]) -> str: ...
54-
def distinct(queryset: QuerySet, base: Optional[QuerySet]) -> QuerySet: ...
53+
def unicode_http_header(value: str | bytes) -> str: ...
54+
def distinct(queryset: QuerySet, base: QuerySet | None) -> QuerySet: ...
5555

56-
SHORT_SEPARATORS: Tuple[str, str]
57-
LONG_SEPARATORS: Tuple[str, str]
58-
INDENT_SEPARATORS: Tuple[str, str]
56+
SHORT_SEPARATORS: tuple[str, str]
57+
LONG_SEPARATORS: tuple[str, str]
58+
INDENT_SEPARATORS: tuple[str, str]
5959

6060
__all__ = [
6161
"coreapi",

rest_framework-stubs/decorators.pyi

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Any, Callable, List, Mapping, Optional, Protocol, Sequence, Type, TypeVar, Union
1+
from collections.abc import Callable, Mapping, Sequence
2+
from typing import Any, Protocol, TypeVar
23

34
from django.http import HttpRequest
45
from django.http.response import HttpResponseBase
@@ -10,7 +11,7 @@ from rest_framework.request import Request
1011
from rest_framework.schemas.inspectors import ViewInspector
1112
from rest_framework.throttling import BaseThrottle
1213
from rest_framework.views import APIView, AsView # noqa: F401
13-
from typing_extensions import Concatenate, Literal, ParamSpec
14+
from typing_extensions import Concatenate, Literal, ParamSpec, TypeAlias
1415

1516
_View = TypeVar("_View", bound=Callable[..., HttpResponseBase])
1617
_P = ParamSpec("_P")
@@ -28,7 +29,7 @@ class MethodMapper(dict):
2829
def options(self, func: _View) -> _View: ...
2930
def trace(self, func: _View) -> _View: ...
3031

31-
_LOWER_CASE_HTTP_VERBS = List[
32+
_LOWER_CASE_HTTP_VERBS: TypeAlias = list[
3233
Literal[
3334
"get",
3435
"post",
@@ -40,7 +41,7 @@ _LOWER_CASE_HTTP_VERBS = List[
4041
]
4142
]
4243

43-
_MIXED_CASE_HTTP_VERBS = List[
44+
_MIXED_CASE_HTTP_VERBS: TypeAlias = list[
4445
Literal[
4546
"GET",
4647
"POST",
@@ -71,26 +72,22 @@ class ViewSetAction(Protocol[_View]):
7172
__call__: _View
7273

7374
def api_view(
74-
http_method_names: Optional[Sequence[str]] = ...,
75+
http_method_names: Sequence[str] | None = ...,
7576
) -> Callable[[Callable[Concatenate[Request, _P], _RESP]], AsView[Callable[Concatenate[HttpRequest, _P], _RESP]]]: ...
76-
def renderer_classes(
77-
renderer_classes: Sequence[Union[BaseRenderer, Type[BaseRenderer]]]
78-
) -> Callable[[_View], _View]: ...
79-
def parser_classes(parser_classes: Sequence[Union[BaseParser, Type[BaseParser]]]) -> Callable[[_View], _View]: ...
77+
def renderer_classes(renderer_classes: Sequence[BaseRenderer | type[BaseRenderer]]) -> Callable[[_View], _View]: ...
78+
def parser_classes(parser_classes: Sequence[BaseParser | type[BaseParser]]) -> Callable[[_View], _View]: ...
8079
def authentication_classes(
81-
authentication_classes: Sequence[Union[BaseAuthentication, Type[BaseAuthentication]]]
82-
) -> Callable[[_View], _View]: ...
83-
def throttle_classes(
84-
throttle_classes: Sequence[Union[BaseThrottle, Type[BaseThrottle]]]
80+
authentication_classes: Sequence[BaseAuthentication | type[BaseAuthentication]],
8581
) -> Callable[[_View], _View]: ...
82+
def throttle_classes(throttle_classes: Sequence[BaseThrottle | type[BaseThrottle]]) -> Callable[[_View], _View]: ...
8683
def permission_classes(permission_classes: Sequence[_PermissionClass]) -> Callable[[_View], _View]: ...
87-
def schema(view_inspector: Optional[Union[ViewInspector, Type[ViewInspector]]]) -> Callable[[_View], _View]: ...
84+
def schema(view_inspector: ViewInspector | type[ViewInspector] | None) -> Callable[[_View], _View]: ...
8885
def action(
89-
methods: Optional[_MIXED_CASE_HTTP_VERBS] = ...,
86+
methods: _MIXED_CASE_HTTP_VERBS | None = ...,
9087
detail: bool = ...,
91-
url_path: Optional[str] = ...,
92-
url_name: Optional[str] = ...,
93-
suffix: Optional[str] = ...,
94-
name: Optional[str] = ...,
88+
url_path: str | None = ...,
89+
url_name: str | None = ...,
90+
suffix: str | None = ...,
91+
name: str | None = ...,
9592
**kwargs: Any,
9693
) -> Callable[[_View], ViewSetAction[_View]]: ...
Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,43 @@
1-
from typing import Any, Callable, Optional, Sequence, Type
1+
from collections.abc import Callable, Sequence
2+
from typing import Any
23

34
from rest_framework.renderers import BaseRenderer
45
from rest_framework.schemas import SchemaGenerator
56
from rest_framework.urlpatterns import _AnyURL
67

78
def get_docs_view(
8-
title: Optional[str] = ...,
9-
url: Optional[str] = ...,
10-
description: Optional[str] = ...,
11-
urlconf: Optional[str] = ...,
12-
renderer_classes: Optional[Sequence[Type[BaseRenderer]]] = ...,
9+
title: str | None = ...,
10+
url: str | None = ...,
11+
description: str | None = ...,
12+
urlconf: str | None = ...,
13+
renderer_classes: Sequence[type[BaseRenderer]] | None = ...,
1314
public: bool = ...,
14-
patterns: Optional[Sequence[_AnyURL]] = ...,
15-
generator_class: Type[SchemaGenerator] = ...,
15+
patterns: Sequence[_AnyURL] | None = ...,
16+
generator_class: type[SchemaGenerator] = ...,
1617
authentication_classes: Sequence[str] = ...,
1718
permission_classes: Sequence[str] = ...,
1819
) -> Callable[..., Any]: ...
1920
def get_schemajs_view(
20-
title: Optional[str] = ...,
21-
url: Optional[str] = ...,
22-
description: Optional[str] = ...,
23-
urlconf: Optional[str] = ...,
24-
renderer_classes: Optional[Sequence[Type[BaseRenderer]]] = ...,
21+
title: str | None = ...,
22+
url: str | None = ...,
23+
description: str | None = ...,
24+
urlconf: str | None = ...,
25+
renderer_classes: Sequence[type[BaseRenderer]] | None = ...,
2526
public: bool = ...,
26-
patterns: Optional[Sequence[_AnyURL]] = ...,
27-
generator_class: Type[SchemaGenerator] = ...,
27+
patterns: Sequence[_AnyURL] | None = ...,
28+
generator_class: type[SchemaGenerator] = ...,
2829
authentication_classes: Sequence[str] = ...,
2930
permission_classes: Sequence[str] = ...,
3031
) -> Callable[..., Any]: ...
3132
def include_docs_urls(
32-
title: Optional[str] = ...,
33-
url: Optional[str] = ...,
34-
description: Optional[str] = ...,
35-
urlconf: Optional[str] = ...,
36-
renderer_classes: Optional[Sequence[Type[BaseRenderer]]] = ...,
33+
title: str | None = ...,
34+
url: str | None = ...,
35+
description: str | None = ...,
36+
urlconf: str | None = ...,
37+
renderer_classes: Sequence[type[BaseRenderer]] | None = ...,
3738
public: bool = ...,
38-
patterns: Optional[Sequence[_AnyURL]] = ...,
39-
generator_class: Type[SchemaGenerator] = ...,
39+
patterns: Sequence[_AnyURL] | None = ...,
40+
generator_class: type[SchemaGenerator] = ...,
4041
authentication_classes: Sequence[str] = ...,
4142
permission_classes: Sequence[str] = ...,
4243
) -> Any: ...

rest_framework-stubs/exceptions.pyi

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1-
from typing import Any, Dict, List, Optional, Sequence, Union
1+
from collections.abc import Sequence
2+
from typing import Any
3+
4+
from typing_extensions import TypeAlias
25

36
from django.http import HttpRequest, JsonResponse
47
from rest_framework.renderers import BaseRenderer
58
from rest_framework.request import Request
69

7-
def _get_error_details(data: Any, default_code: Optional[str] = ...) -> Any: ...
10+
def _get_error_details(data: Any, default_code: str | None = ...) -> Any: ...
811
def _get_codes(detail: Any) -> Any: ...
912
def _get_full_details(detail: Any) -> Any: ...
1013

1114
class ErrorDetail(str):
12-
code: Optional[str] = None
13-
def __new__(cls, string: str, code: Optional[str] = ...): ...
15+
code: str | None
16+
def __new__(cls, string: str, code: str | None = ...): ...
1417

15-
_Detail = Union[str, List[Any], Dict[str, Any]]
18+
_Detail: TypeAlias = str | list[Any] | dict[str, Any]
1619

1720
class APIException(Exception):
18-
status_code: int = ...
19-
default_detail: _Detail = ...
20-
default_code: str = ...
21+
status_code: int
22+
default_detail: _Detail
23+
default_code: str
2124

2225
detail: _Detail
23-
def __init__(self, detail: Optional[_Detail] = ..., code: Optional[str] = ...) -> None: ...
26+
def __init__(self, detail: _Detail | None = ..., code: str | None = ...) -> None: ...
2427
def get_codes(self) -> Any: ...
2528
def get_full_details(self) -> Any: ...
2629

@@ -32,26 +35,24 @@ class PermissionDenied(APIException): ...
3235
class NotFound(APIException): ...
3336

3437
class MethodNotAllowed(APIException):
35-
def __init__(self, method: str, detail: Optional[_Detail] = ..., code: Optional[str] = ...) -> None: ...
38+
def __init__(self, method: str, detail: _Detail | None = ..., code: str | None = ...) -> None: ...
3639

3740
class NotAcceptable(APIException):
38-
available_renderers: Optional[Sequence[BaseRenderer]]
41+
available_renderers: Sequence[BaseRenderer] | None
3942
def __init__(
4043
self,
41-
detail: Optional[_Detail] = ...,
42-
code: Optional[str] = ...,
43-
available_renderers: Optional[Sequence[BaseRenderer]] = ...,
44+
detail: _Detail | None = ...,
45+
code: str | None = ...,
46+
available_renderers: Sequence[BaseRenderer] | None = ...,
4447
) -> None: ...
4548

4649
class UnsupportedMediaType(APIException):
47-
def __init__(self, media_type: str, detail: Optional[_Detail] = ..., code: Optional[str] = ...) -> None: ...
50+
def __init__(self, media_type: str, detail: _Detail | None = ..., code: str | None = ...) -> None: ...
4851

4952
class Throttled(APIException):
50-
extra_detail_singular: str = ...
51-
extra_detail_plural: str = ...
52-
def __init__(self, wait: Optional[float] = ..., detail: Optional[_Detail] = ..., code: Optional[str] = ...): ...
53-
54-
def server_error(request: Union[HttpRequest, Request], *args: Any, **kwargs: Any) -> JsonResponse: ...
55-
def bad_request(
56-
request: Union[HttpRequest, Request], exception: Exception, *args: Any, **kwargs: Any
57-
) -> JsonResponse: ...
53+
extra_detail_singular: str
54+
extra_detail_plural: str
55+
def __init__(self, wait: float | None = ..., detail: _Detail | None = ..., code: str | None = ...): ...
56+
57+
def server_error(request: HttpRequest | Request, *args: Any, **kwargs: Any) -> JsonResponse: ...
58+
def bad_request(request: HttpRequest | Request, exception: Exception, *args: Any, **kwargs: Any) -> JsonResponse: ...

0 commit comments

Comments
 (0)