Skip to content

Commit

Permalink
Batch of latest changes (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
last-partizan authored Sep 15, 2024
1 parent 5bf5fbb commit 04cb561
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 224 deletions.
8 changes: 4 additions & 4 deletions coreschema-stubs/schemas.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Object(Schema):
min_properties: Any | None = ...,
pattern_properties: Any | None = ...,
additional_properties: bool = ...,
**kwargs: Any
**kwargs: Any,
) -> None: ...
def validate(self, value: Any, context: Any | None = ...) -> list[Error]: ...

Expand All @@ -61,7 +61,7 @@ class Array(Schema):
min_items: Any | None = ...,
unique_items: bool = ...,
additional_items: bool = ...,
**kwargs: Any
**kwargs: Any,
) -> None: ...
def validate(self, value: Any, context: Any | None = ...) -> list[Error]: ...

Expand All @@ -80,7 +80,7 @@ class Number(Schema):
exclusive_minimum: bool = ...,
exclusive_maximum: bool = ...,
multiple_of: int | None = ...,
**kwargs: Any
**kwargs: Any,
) -> None: ...
def validate(self, value: Any, context: Any | None = ...) -> list[Error]: ...

Expand All @@ -101,7 +101,7 @@ class String(Schema):
min_length: int | None = ...,
pattern: str | None = ...,
format: Any | None = ...,
**kwargs: Any
**kwargs: Any,
) -> None: ...
def validate(self, value: Any, context: Any | None = ...) -> list[Error]: ...

Expand Down
205 changes: 23 additions & 182 deletions poetry.lock

Large diffs are not rendered by default.

16 changes: 7 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ packages = [
]

[tool.poetry.dependencies]
python = "^3.7"
python = "^3.8"
typing_extensions = { version = "^4.6", python = "<3.11" }

[tool.poetry.group.dev.dependencies]
Expand All @@ -27,16 +27,15 @@ flake8 = "^3.8"
flake8-pyi = "^20.10"
mypy = "^1.4"
isort = "5.10.1"
black = "^22.10.0"
types-requests = "^2.28.11"
ruff = "^0.0.261"
ruff = "^0.6.5"
pyright = "^1.1.318"

[tool.black]
[tool.ruff]
target-version = "py38"
line-length = 120
include = '\.pyi?$'

[tool.ruff]
[tool.ruff.lint]
select = [
"E",
"F",
Expand Down Expand Up @@ -78,14 +77,13 @@ ignore = [
"N818", # some exceptions have bad names
"N801", # some class names have bad names
"ERA001", # false positives
"UP007", # We're using Union/Optional here.
]
unfixable = [
"ERA001",
] # we want to check ourselves before we delete commented out code.
update-check = false
target-version = "py38"

[tool.ruff.flake8-tidy-imports]
[tool.ruff.lint.flake8-tidy-imports]
# Disallow all relative imports.
ban-relative-imports = "all"

Expand Down
4 changes: 2 additions & 2 deletions rest_framework-stubs/decorators.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ from typing import (
from django.db.models import QuerySet
from django.http.response import HttpResponseBase
from rest_framework.authentication import BaseAuthentication
from rest_framework.filters import _FilterBackendProtocol
from rest_framework.filters import FilterBackendProtocol
from rest_framework.parsers import BaseParser
from rest_framework.permissions import _PermissionClass
from rest_framework.renderers import BaseRenderer
Expand Down Expand Up @@ -112,7 +112,7 @@ def action(
authentication_classes: _AuthClassesParam = ...,
renderer_classes: _RenderClassesParam = ...,
parser_classes: _ParserClassesParam = ...,
filter_backends: Sequence[type[_FilterBackendProtocol]] = ...,
filter_backends: Sequence[type[FilterBackendProtocol]] = ...,
lookup_field: str = ...,
lookup_url_kwarg: str | None = ...,
queryset: QuerySet[Any] = ...,
Expand Down
7 changes: 3 additions & 4 deletions rest_framework-stubs/filters.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ from rest_framework.request import Request
from rest_framework.views import APIView

_MT = TypeVar("_MT", bound=Model)
_Q = TypeVar("_Q", bound=QuerySet[Any])

class _FilterBackendProtocol(Protocol):
def filter_queryset(self, request: Any, queryset: _Q, view: APIView) -> _Q: ...
class FilterBackendProtocol(Protocol):
def filter_queryset(self, request: Request, queryset: QuerySet[_MT], view: APIView) -> QuerySet[_MT]: ...

class BaseFilterBackend:
def filter_queryset(self, request: Any, queryset: _Q, view: APIView) -> _Q: ...
def filter_queryset(self, request: Request, queryset: QuerySet[_MT], view: APIView) -> QuerySet[_MT]: ...
def get_schema_fields(self, view: APIView) -> list[Any]: ...
def get_schema_operation_parameters(self, view: APIView) -> Any: ...

Expand Down
4 changes: 2 additions & 2 deletions rest_framework-stubs/generics.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ from django.db.models import Manager, Model
from django.db.models.query import QuerySet
from django.http.response import HttpResponse
from rest_framework import mixins, views
from rest_framework.filters import _FilterBackendProtocol
from rest_framework.filters import FilterBackendProtocol
from rest_framework.pagination import BasePagination
from rest_framework.request import Request
from rest_framework.response import Response
Expand All @@ -24,7 +24,7 @@ class GenericAPIView(views.APIView):
serializer_class: type[BaseSerializer] | None = ...
lookup_field: str = ...
lookup_url_kwarg: str | None = ...
filter_backends: Sequence[type[_FilterBackendProtocol]] = ...
filter_backends: Sequence[type[FilterBackendProtocol]] = ...
pagination_class: type[BasePagination] | None = ...
def get_object(self) -> Any: ...
def get_serializer(self, *args: Any, **kwargs: Any) -> BaseSerializer: ...
Expand Down
2 changes: 1 addition & 1 deletion rest_framework-stubs/renderers.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class BrowsableAPIRenderer(BaseRenderer):
view_instance: APIView,
request: Request,
*args: Any,
**kwargs: Any
**kwargs: Any,
) -> BaseSerializer: ...
def get_rendered_html_form(self, data: Any, view: APIView, method: str, request: Request) -> Any: ...
def render_form_for_serializer(self, serializer: BaseSerializer) -> Any: ...
Expand Down
4 changes: 2 additions & 2 deletions rest_framework-stubs/reverse.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ def reverse(
kwargs: Mapping[str, Any] | None = ...,
request: HttpRequest | None = ...,
format: str | None = ...,
**extra: Any
**extra: Any,
) -> str: ...
def _reverse(
viewname: str,
args: Sequence[Any] | None = ...,
kwargs: Mapping[str, Any] | None = ...,
request: HttpRequest | None = ...,
format: str | None = ...,
**extra: Any
**extra: Any,
) -> str: ...

reverse_lazy: Callable[..., str] = ...
1 change: 1 addition & 0 deletions rest_framework-stubs/serializers.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class ModelSerializer(Serializer, BaseSerializer):
exclude: Sequence[str] | None
depth: int | None
extra_kwargs: dict[str, dict[str, Any]]

def __init__(
self,
instance: None | Any | Sequence[Any] | QuerySet[Any] | Manager[Any] = ...,
Expand Down
26 changes: 13 additions & 13 deletions rest_framework-stubs/test.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class APIRequestFactory(DjangoRequestFactory):
secure: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Request: ...
def post( # type: ignore [override]
self,
Expand All @@ -69,7 +69,7 @@ class APIRequestFactory(DjangoRequestFactory):
content_type: str | None = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Request: ...
def put( # type: ignore [override]
self,
Expand All @@ -79,7 +79,7 @@ class APIRequestFactory(DjangoRequestFactory):
content_type: str | None = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Request: ...
def patch( # type: ignore [override]
self,
Expand All @@ -89,7 +89,7 @@ class APIRequestFactory(DjangoRequestFactory):
content_type: str | None = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Request: ...
def delete( # type: ignore [override]
self,
Expand All @@ -99,7 +99,7 @@ class APIRequestFactory(DjangoRequestFactory):
content_type: str | None = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Request: ...
def options( # type: ignore [override]
self,
Expand All @@ -109,7 +109,7 @@ class APIRequestFactory(DjangoRequestFactory):
content_type: Any | None = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Request: ...
def generic( # type: ignore[override]
self,
Expand All @@ -120,7 +120,7 @@ class APIRequestFactory(DjangoRequestFactory):
secure: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Request: ...

class ForceAuthClientHandler(ClientHandler):
Expand All @@ -139,7 +139,7 @@ class APIClient(APIRequestFactory, DjangoClient): # pyright: ignore[reportIncom
follow: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Response: ...
def post( # type: ignore [override]
self,
Expand All @@ -150,7 +150,7 @@ class APIClient(APIRequestFactory, DjangoClient): # pyright: ignore[reportIncom
follow: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Response: ...
def put( # type: ignore [override]
self,
Expand All @@ -161,7 +161,7 @@ class APIClient(APIRequestFactory, DjangoClient): # pyright: ignore[reportIncom
follow: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Response: ...
def patch( # type: ignore [override]
self,
Expand All @@ -172,7 +172,7 @@ class APIClient(APIRequestFactory, DjangoClient): # pyright: ignore[reportIncom
follow: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Response: ...
def delete( # type: ignore [override]
self,
Expand All @@ -183,7 +183,7 @@ class APIClient(APIRequestFactory, DjangoClient): # pyright: ignore[reportIncom
follow: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Response: ...
def options( # type: ignore [override]
self,
Expand All @@ -194,7 +194,7 @@ class APIClient(APIRequestFactory, DjangoClient): # pyright: ignore[reportIncom
follow: bool = ...,
*,
QUERY_STRING: str = ...,
**extra: str
**extra: str,
) -> Response: ...
def logout(self) -> None: ...

Expand Down
2 changes: 1 addition & 1 deletion rest_framework-stubs/versioning.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class BaseVersioning:
kwargs: Mapping[str, Any] | None = ...,
request: Request | None = ...,
format: str | None = ...,
**extra: Any
**extra: Any,
) -> str: ...
def is_allowed_version(self, version: str | None) -> bool: ...

Expand Down
8 changes: 4 additions & 4 deletions s/lint
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ set -ex

# format code
if [[ $CI ]]; then
./.venv/bin/black --check .
./.venv/bin/ruff .
./.venv/bin/ruff format --check
./.venv/bin/ruff check
else
./.venv/bin/black .
./.venv/bin/ruff . --fix
./.venv/bin/ruff format
./.venv/bin/ruff check --fix
fi

./.venv/bin/pyright tests typings
Expand Down
27 changes: 27 additions & 0 deletions tests/test_restframework.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from typing import Sequence

from rest_framework.decorators import permission_classes
from rest_framework.filters import FilterBackendProtocol
from rest_framework.generics import GenericAPIView
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.test import APIClient
from typing_extensions import assert_type
Expand All @@ -15,3 +19,26 @@ def test_test_client_types() -> None:
def test_decorator_types() -> None:
permission_classes([IsAuthenticated])
permission_classes([IsAuthenticated | IsAdminUser])


def test_filter_backends_types() -> None:
"""
django-filter does not use typing, so we're testing if untyped code also works fine
with our types.
https://github.com/carltongibson/django-filter/pull/1585
"""

class DjangoFilterBackend:
def filter_queryset(self, request, queryset, view): # type: ignore
filterset = self.get_filterset(request, queryset, view) # type: ignore
return filterset.qs

class BookAPIView(GenericAPIView):
filter_backends = (DjangoFilterBackend,)

# mypy and pyright works differently here:
# mypy: Expression is of type "tuple[type[DjangoFilterBackend]]", not "Sequence[type[FilterBackendProtocol]]" [assert-type]
# Disable this check for now in mypy.
# At least assigning to filter_backends works fine, that's our main concern here.
assert_type(BookAPIView.filter_backends, Sequence[type[FilterBackendProtocol]]) # type: ignore[assert-type]

0 comments on commit 04cb561

Please sign in to comment.