Use __new__ instead of __init__ in serializers#315
Conversation
|
This has been in the back of my mind also. It would be great if this works. AFAIK But I think it's possible to convince mypy developers to change this requirement. Please add a test case demonstrating whether this works or not. |
|
The CI errors will be fixed in #316. |
Well EDIT: This is not the case for So I've added a |
|
Ok this seems to work fine when using IntBaseSerializer = serializers.BaseSerializer[int]
test_serializer = IntBaseSerializer([1, 2], many=True)
reveal_type(test_serializer) # N: Revealed type is "rest_framework.serializers.ListSerializer[builtins.int]"But when defining a custom serializer: class TestSerializer(serializers.Serializer[int]):
pass
test_serializer = TestSerializer(instance=[1, 2], many=True)
reveal_type(test_serializer) # N: Revealed type is "main.TestSerializer"We get the wrong type, possibly because mypy isn't using the I did some tests locally, and it seems that this issue is specific to mypy: from __future__ import annotations
class A:
def __new__(cls) -> B:
return B()
class B(A):
pass
class C(A):
pass
a = C()
reveal_type(a) # Revealed type is "C", but got B with pyright (Pylance)I'll open a ticket |
overload definition is subject to change, as it is missing some arguments.
|
I found there's already an open mypy issue about this: python/mypy#8330 |
Attempt to fix #260. This is starting to be really tricky to handle, so I don't know if this is a viable option. Regarding
ModelSerializer, we might want to define the sameoverload, and only allow specific types forinstancewith respect tomany(e.g. ifmany=False, only allow_MT, but I'm unsure there's other types that could be allowed as well).Note:
__init__has been omitted, otherwise mypy will not infer the correct return type from__new__