django-ninja
django-ninja copied to clipboard
Fix `paginate` Decorator Typing
Paginating your endpoint transforms the collection return type into one that returns a dict, however, this isn't reflected in the final type.
Let's take this example:
@api.get("/invalid1", response={200: None})
@paginate
def invalid1(request: HttpRequest) -> list[Any]:
return [1, 2, 3]
reveal_type(invalid1) # Type of "invalid1" is "(...) -> Unknown
This also leads to typing errors when passing in a pagination class (with Pyright):
@api.get("/invalid1", response={200: None})
@paginate(PageNumberPagination) # Untyped function decorator obscures type of function; ignoring decorator
def invalid1(request: HttpRequest) -> list[Any]:
return [1, 2, 3]
This PR sets up overloading for paginate so that type can be correctly inferred in both cases. Operating under the assumption that assumption that ninja already makes that paginate_queryset returns dict[str, Any]
For our first example, we now get:
@api.get("/invalid1", response={200: None})
@paginate
def invalid1(request: HttpRequest) -> list[Any]:
return [1, 2, 3]
reveal_type(invalid1) # (HttpRequest) -> Dict[str, Any]
Other Changes
- While unlikely, it's not enforced that you paginate a queryset, technically any collection with
lenis supported. Therefore, I switched some of theQuerySettypes toSequenceto better reflect this. - Added overload decorated functions to be excluded from coverage requirements, since they're purely for typing.
Hi @max-muoto
Thank you for contribution Could you fix conflicts with the latest version ?
Hi @max-muoto
Thank you for contribution Could you fix conflicts with the latest version ?
I'll have to do a bit of reworking with the support for async pagination, but I'll ping you once this is ready again, I'll move it back to a draft in the mean-time.