Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expression has type "SlugRelatedField[<nothing>]" #168

Open
Phil-Barber opened this issue Sep 23, 2021 · 8 comments
Open

expression has type "SlugRelatedField[<nothing>]" #168

Phil-Barber opened this issue Sep 23, 2021 · 8 comments
Labels
bug Something isn't working

Comments

@Phil-Barber
Copy link

I have the following serializer:

class ReportConfigurationSerializer(serializers.ModelSerializer[ReportScheduleConfiguration]):
    created_by = serializers.SlugRelatedField(read_only=True, slug_field="email")
    generation_settings = ReportGenerationSettingsJSONField(read_only=True)
    send_time_zone = TimeZoneSerializerField()

    class Meta:
        model = ReportScheduleConfiguration
        fields = (
            "id",
            "name",
            "send_time",
            "send_time_zone",
            "recipients",
            "report_type",
            "generation_settings",
        )

I would expect that mypy can detect the type of created_by, instead I have the error:
Need type annotation for 'created_by' [var-annotated]

If I add a type annotation just for example eg:
created_by: str = serializers.SlugRelatedField(read_only=True, slug_field="email")
The error updates to:
Incompatible types in assignment (expression has type "SlugRelatedField[<nothing>]", variable has type "str") [assignment]

I'm reasonably unfamiliar with typing, so trying to decipher what <nothing> meant took me forever as its not documented currently.
My understanding is that somewhere in trying to decipher the type for SlugRelatedField mypy believes some code is undefined and so exits early. I believe this to be a problem with this library rather than my implementation, but I am more than happy to provide additional details!

Libraries

name = "djangorestframework", version = "3.12.4"
name = "djangorestframework-stubs", version = "1.4.0"
name = "django", version = "2.2.24"
Python 3.9.7

@Phil-Barber Phil-Barber added the bug Something isn't working label Sep 23, 2021
@intgr
Copy link
Contributor

intgr commented Nov 3, 2021

Here's a testable example exhibiting the behavior:

from rest_framework import serializers
from django.contrib.auth.models import User, Group

class TestSerializer(serializers.ModelSerializer):
    username = serializers.CharField(max_length=150)
    group_ids = serializers.PrimaryKeyRelatedField(many=True, source="groups", read_only=True)
    group_names = serializers.SlugRelatedField(many=True, slug_field="name", source="groups", read_only=True)

    class Meta:
        model = User
        fields = ["username", "group_ids", "group_names"]

Output:

main:6: error: Need type annotation for 'group_ids'
main:7: error: Need type annotation for 'group_names'

What I don't understand is, why is it complaining about the group_ids, group_names fields but not username?

Anyway, one way to shut it up is just annotate it as field type:

from rest_framework.fields import Field
...
    group_ids: Field = serializers.PrimaryKeyRelatedField(many=True, source="groups", read_only=True)

or if you need a more precise type, you can quote it and hint the type vars too:

    group_ids: "PrimaryKeyRelatedField[Group, ...]" = PrimaryKeyRelatedField(many=True, source="groups", read_only=True)

@sobolevn
Copy link
Member

sobolevn commented Nov 3, 2021

Thanks a lot, this is a big help. PR is more than welcome! 👍

@intgr
Copy link
Contributor

intgr commented Nov 3, 2021

I can't submit a PR because my "fix" (more like workaround) can only be applied in user code. 😄

Do you have any ideas why CharField and similar simple fields don't cause this "Need type annotation" inspection, but RelatedFields do?

I skimmed the type definitions and plugin code, and couldn't figure it out. Getting an answer to that would probably help solve it.

@niall-byrne
Copy link

I encountered this same problem with StringRelatedField... is this a workaround or the intended pattern?

contributors: "serializers.StringRelatedField[Artist]" =\
    serializers.StringRelatedField(many=True)

@sobolevn
Copy link
Member

This totally can be improved.

@pablobuenaposada
Copy link

nothing better to fix this?

@sparrowt
Copy link

Hitting this too - sadly we just have # type: ignore on the end of the line for all SlugRelatedField :(

@ysmolski
Copy link

This bug is rather frustrating.

Linkid added a commit to Linkid/djangorestframework-stubs that referenced this issue May 7, 2024
Remove the data type TypeVar in favor of Any. Then subclasses don't have
to deal with this rule anymore.

Ref typeddjango#168
Linkid added a commit to Linkid/djangorestframework-stubs that referenced this issue May 7, 2024
Linkid added a commit to Linkid/djangorestframework-stubs that referenced this issue May 7, 2024
Remove the data type TypeVar in favor of Any. Then subclasses don't have
to deal with this rule anymore.

Ref typeddjango#168
Linkid added a commit to Linkid/djangorestframework-stubs that referenced this issue May 7, 2024
Linkid added a commit to Linkid/djangorestframework-stubs that referenced this issue May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

7 participants