Files
trustme/core/utils/router.py

55 lines
2.2 KiB
Python

from typing import Type, Optional, Self, override
from rest_framework.viewsets import ViewSetMixin # type: ignore
from rest_framework.routers import DefaultRouter # type: ignore
class TypedRouter(DefaultRouter):
"""
A subclass of DRF's `rest_framework.routers.DefaultRouter` that adds proper static
type annotations to certain methods — particularly the `register` method.
This resolves issues with static analysis tools such as MyPy and Pyright,
which normally raise warnings or require `# type: ignore` comments due to the
original method's lack of strict typing.
Benefits:
- Eliminates the need to use `# type: ignore` when calling `.register(...)`
- Improves type safety by enforcing that only subclasses of `ViewSetMixin` are passed
- Enhances developer experience (DX) in statically typed projects
- Promotes DRY principles by reducing repetitive ignores across the codebase
This class does not modify any runtime behavior of `DefaultRouter`. It is purely a DX
and tooling improvement for typed Python projects using Django REST Framework (DRF).
Example:
from my_project.routers import TypedRouter
from my_app.api import UserViewSet
router = TypedRouter()
router.register("users", UserViewSet, basename="user")
"""
@override
def register( # type: ignore
self,
prefix: str,
viewset: Type[ViewSetMixin],
basename: Optional[str] = None,
**kwargs: object
) -> Self:
"""
Registers a viewset with a given URL prefix and optional basename, with proper type hints
to improve static analysis (e.g., with MyPy or Pyright) when using DRF's DefaultRouter.
This method overrides `DefaultRouter.register()` to annotate the expected `viewset` type
as a subclass of `ViewSetMixin`, which reflects how DRF expects viewsets to behave.
Useful for eliminating `# type: ignore` comments and improving autocompletion.
See also:
- DRF Router documentation: https://www.django-rest-framework.org/api-guide/routers/
"""
super().register(prefix=prefix, viewset=viewset, basename=basename, **kwargs) # type: ignore
return self