djangorestframework-stubs
djangorestframework-stubs copied to clipboard
Incorrect `instance` type in `ModelSerializer`
# -*- coding: utf-8 -*-
from rest_framework import serializers
from server.apps.main.models import BlogPost, User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'email']
class BlogPostSerializer(serializers.HyperlinkedModelSerializer):
author = UserSerializer()
class Meta:
model = BlogPost
fields = ['author', 'text', 'is_published', 'created_at']
reveal_type(BlogPostSerializer)
Output:
» PYTHONPATH="$PYTHONPATH:$PWD" mypy server
server/apps/main/serializers.py:21: note: Revealed type is 'def (instance: Union[Any, None] =, data: Any =, **kwargs: Any) -> server.apps.main.serializers.BlogPostSerializer'
Reproduction: https://github.com/sobolevn/django_stubs_example
It seems like instance should be Optional[BlogPost] in this particular case, not Optional[Any].
It would be great to make ModelSerializers generic. Otherwise, you end up fighting against LSP
Should be resolved. @sobolevn
@Goldziher let's write explicit tests for both ModelSerializer and HyperlinkedModelSerializer.
Because currently we don't have them: https://github.com/typeddjango/djangorestframework-stubs/blob/master/test-data/typecheck/test_serializers.yml
And close this issue via a PR! 👍
Now that ModelSerializer is generic...what is the syntax to subclass from it?
class ItemSerializer(serializers.ModelSerializer):
^ Missing type parameters for generic type "ModelSerializer" mypy
class ItemSerializer(serializers.ModelSerializer[Item]):
@henribru Thanks for responding! I should have mentioned that I did try that and mypy was happy, but the app crashed with:
TypeError: 'SerializerMetaclass' object is not subscriptable
I am using Python 3.7. Do I need to use a newer version of Python? (or perhaps a newer version of DRF?)
You need to use DRF 3.12. If you need to stay on an earlier version you can do this: https://mypy.readthedocs.io/en/stable/runtime_troubles.html#using-classes-that-are-generic-in-stubs-but-not-at-runtime
There's also a workaround using monkeypatch, but I don't know the details of that.
@henribru Thank you, SOO MUCH!
Upgrading DRF fixed my SerializerMetaclass type issue, and from the article you linked to, I found that adding
from __future__ import annotations
to the top of all my Python 3.7 files fixed virtually all of the other typings issues I was having.
I feel like I owe you at least a steak dinner (or the vegetarian equivalent if you don't eat steak...) Do you have a Patreon or PayPal or other way to donate?