djangorestframework-stubs
djangorestframework-stubs copied to clipboard
__name__ attribute missing from the ViewSetAction type
Bug report
What's wrong
mypy doesn't recognize the __name__
attribute of an action. See minimal example with error below:
from typing import Any
from rest_framework import decorators, viewsets
from rest_framework.request import Request
from rest_framework.response import Response
class TestViewSet(viewsets.GenericViewSet[Any]):
@decorators.action(methods=["get"], detail=False)
def example_action(self, request: Request, **kwargs: Any) -> Response:
return Response({})
TestViewSet.example_action.__name__ # error: "ViewSetAction[Callable[[TestViewSet, Request, KwArg(Any)], Response]]" has no attribute "__name__" [attr-defined]
How is that should be
The above snippet should not raise an error. In order to achieve this we can add the __name__
attribute to the ViewSetAction. The actions are all methods so the __name__
attribute is always defined. See also below for the use case.
# rest_framework-stubs/decorators.pyi
class ViewSetAction(Protocol[_View]):
detail: bool
methods: _LOWER_CASE_HTTP_VERBS
url_path: str
url_name: str
kwargs: Mapping[str, Any]
mapping: MethodMapper
__call__: _View
__name__: str # <-- Defining the __name__ attribute here would solve the issue
Use case
When checking actions in viewset methods, we could use self.action == self.__class__.example_action.__name__
instead of self.action == "example_action"
to limit the potential risk of action naming update (type checkers would detect the attribute error) and avoid the use of error-prone strings.
System information
-
OS
: Windows -
python
version: 3.10 -
django
version: 4.1 -
mypy
version: 1.4.1 -
django-stubs
version: 4.2.3
Makes sense. Also it seems the methods
attribute doesn't actually exist.
@intgr I can work on this issue, please assign it to me.
@Sakhi29 Sorry, your comment got lost among all notifications I'm receiving. I've assigned you. In the future, there's no need to wait for assigment, just fire a PR 😄
up