Skip to content

Commit

Permalink
Fix class hierachy and TypeVars of Serializer classes (#520)
Browse files Browse the repository at this point in the history
* `ModelSerializer` was incorrectly deriving from `Serializer[Any]` and `BaseSerializer[T]`;
  replaced with `Serializer[T]`.
  This brings it into sync with DRF upstream.
* Added TypeVar to `HyperlinkedModelSerializer` class.
* Removed unnecessary `Generic[]` where implicit TypeVars are sufficient.

  https://mypy.readthedocs.io/en/stable/generics.html#defining-subclasses-of-generic-classes

  > If there are no Generic[...] in bases, then all type variables are collected in the lexicographic order (i.e. by first appearance).
  • Loading branch information
intgr committed May 2, 2024
1 parent 6e22a6f commit 9970b74
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 13 deletions.
4 changes: 2 additions & 2 deletions rest_framework-stubs/relations.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Callable, Iterable, Mapping, Sequence
from typing import Any, Generic, TypeVar
from typing import Any, TypeVar

from django.db.models import Manager, Model, QuerySet
from django_stubs_ext import StrOrPromise
Expand Down Expand Up @@ -31,7 +31,7 @@ _MT = TypeVar("_MT", bound=Model)
_DT = TypeVar("_DT") # Data Type
_PT = TypeVar("_PT") # Primitive Type

class RelatedField(Generic[_MT, _DT, _PT], Field[_MT, _DT, _PT, Any]):
class RelatedField(Field[_MT, _DT, _PT, Any]):
queryset: QuerySet[_MT] | Manager[_MT] | None
html_cutoff: int | None
html_cutoff_text: str | None
Expand Down
17 changes: 6 additions & 11 deletions rest_framework-stubs/serializers.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from _typeshed import Incomplete
from collections.abc import Iterable, Iterator, Mapping, MutableMapping, Sequence
from typing import Any, ClassVar, Generic, Literal, NoReturn, TypeVar
from typing import Any, ClassVar, Literal, NoReturn, TypeVar

from django.db import models
from django.db.models import Manager, Model, QuerySet
Expand Down Expand Up @@ -73,7 +73,7 @@ ALL_FIELDS: str
_MT = TypeVar("_MT", bound=Model) # Model Type
_IN = TypeVar("_IN") # Instance Type

class BaseSerializer(Generic[_IN], Field[Any, Any, Any, _IN]):
class BaseSerializer(Field[Any, Any, Any, _IN]):
partial: bool
many: bool
instance: _IN | None
Expand Down Expand Up @@ -124,10 +124,7 @@ class SerializerMetaclass(type):

def as_serializer_error(exc: Exception) -> dict[str, list[ErrorDetail]]: ...

class Serializer(
BaseSerializer[_IN],
metaclass=SerializerMetaclass,
):
class Serializer(BaseSerializer[_IN], metaclass=SerializerMetaclass):
_declared_fields: dict[str, Field]
default_error_messages: ClassVar[dict[str, StrOrPromise]]
def get_initial(self) -> Any: ...
Expand All @@ -149,9 +146,7 @@ class Serializer(
@property
def errors(self) -> ReturnDict: ...

class ListSerializer(
BaseSerializer[_IN],
):
class ListSerializer(BaseSerializer[_IN]):
child: Field | BaseSerializer | None
many: bool
default_error_messages: ClassVar[dict[str, StrOrPromise]]
Expand Down Expand Up @@ -190,14 +185,14 @@ class ListSerializer(

def raise_errors_on_nested_writes(method_name: str, serializer: BaseSerializer, validated_data: Any) -> None: ...

class ModelSerializer(Serializer, BaseSerializer[_MT]):
class ModelSerializer(Serializer[_MT]):
serializer_field_mapping: dict[type[models.Field], type[Field]]
serializer_related_field: type[RelatedField]
serializer_related_to_field: type[RelatedField]
serializer_url_field: type[RelatedField]
serializer_choice_field: type[Field]
url_field_name: str | None
instance: _MT | Sequence[_MT] | None
instance: _MT | Sequence[_MT] | None # type: ignore[assignment]

class Meta:
model: type[_MT] # type: ignore
Expand Down

0 comments on commit 9970b74

Please sign in to comment.