pyrefly icon indicating copy to clipboard operation
pyrefly copied to clipboard

Incorrect `bad-override` for APIView.permission_classes in Django REST Framework

Open AhmWael opened this issue 1 month ago • 1 comments

Describe the Bug

Pyrefly reports a bad-override error when overriding permission_classes in Django REST Framework APIView subclasses.

Example:

from rest_framework.views import APIView
from rest_framework.permissions import BasePermission

class HasRolePermission(BasePermission):
    allowed_roles = []

class IsAdmin(HasRolePermission):
    allowed_roles = ["admin"]

class UserSearchAPIView(APIView):
    permission_classes = [IsAdmin]  # only admins can use it

class ProfileView(APIView):
    permission_classes = [IsAuthenticated]

Pyrefly output:

ERROR Class member `UserSearchAPIView.permission_classes` overrides parent class `APIView` in an inconsistent manner [bad-override]

ERROR Class member `ProfileView.permission_classes` overrides parent class `APIView` in an inconsistent manner [bad-override]
`ProfileView.permission_classes` has type `list[type[IsAuthenticated]]`, which is not consistent with `bool | dict[str, str] | dict[str, None] | int | list[str] | list[Any] | list[Unknown] | str | Unknown | None` in `APIView.permission_classes` (the type of read-write attributes cannot be changed)

Django REST Framework allows permission_classes to be a list of permission classes (list[type[BasePermission]]), which is exactly what my code uses.

Sandbox Link

No response

(Only applicable for extension issues) IDE Information

No response

AhmWael avatar Nov 27 '25 17:11 AhmWael

I think this is effectively a contextual typing problem: for attributes defined in class bodies, we currently will use the assigned expression's inferred type even if an ancestor has an explicit annotation.

Because lists are invariant, this causes a type error; we probably should rethink this.

In the meantime, you can probably work around the problem by adding an annotation list[Any] to the attribute giving you problems

stroxler avatar Nov 28 '25 02:11 stroxler