djangorestframework-stubs icon indicating copy to clipboard operation
djangorestframework-stubs copied to clipboard

GenericAPIView has missing type parameters, but when added 'type' object is not subscriptable

Open XF-FW opened this issue 2 years ago • 2 comments

Bug report

What's wrong

When using mypy with strict=true, it issues the following error: Missing type parameters for generic type "GenericAPIView".

So, I check the type and add it, but I'm now getting a runtime error: TypeError: 'type' object is not subscriptable.

I am using django_stubs_ext.monkeypatch(), which solves the problem for other similar issues.

I haven't test it on its own, but this should suffice, as a reproducible test:

from rest_framework.generics import GenericAPIView

class ShouldWorkView(GenericAPIView[None]):
   ...

How is that should be

The above example should pass, with no issues.

System information

  • OS: Arch
  • python version: 3.10
  • django version: 4.0.7
  • mypy version: 0.942
  • django-stubs version: 1.12.0

XF-FW avatar Sep 21 '22 22:09 XF-FW

I believe you're hitting this issue: https://mypy.readthedocs.io/en/latest/runtime_troubles.html#using-classes-that-are-generic-in-stubs-but-not-at-runtime. The solution suggested on that doc page worked for me.

ewiner avatar Sep 22 '22 05:09 ewiner

Yep, that worked. Thanks!

It still feels like a workaround, so I'll leave this open. If the maintainers feel like this should be the default behavior, feel free to close it.

XF-FW avatar Sep 22 '22 10:09 XF-FW

The same thing happens when trying to subclass PrimaryKeyRelatedField.

Edit: And Field.

XF-FW avatar Nov 05 '22 15:11 XF-FW

You can pass the classes you want to monkeypatch in the extra_classes parameter to django_stubs_ext.monkeypatch().

Example:

import django_stubs_ext
from rest_framework import fields, generics

django_stubs_ext.monkeypatch(
    extra_classes=(fields.Field, generics.GenericAPIView)
)

or you can manually monkeypatch them:

from rest_framework import fields, generics

for cls in (fields.Field, generics.GenericAPIView):
    cls.__class_getitem__ = classmethod(  # type: ignore[attr-defined]
        lambda cls, *args, **kwargs: cls
    )

monosans avatar Nov 18 '22 20:11 monosans

Thank you! That works perfectly.

XF-FW avatar Nov 18 '22 20:11 XF-FW