Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

format_suffix_patterns should have covariant type for urlpatterns parameter #184

Open
peterschutt opened this issue Jan 23, 2022 · 3 comments
Labels
bug Something isn't working

Comments

@peterschutt
Copy link

Version 1.4.0 of DRF-stubs and Following along with the DRF tutorial I've got the following pattern (mypy output inline in comments):

urlpatterns = [
    path("tree/", views.NodeList.as_view()),
    path("tree/<int:pk>", views.NodeDetail.as_view()),
]

# reveal_type(urlpatterns)  # Revealed type is "builtins.list[django.urls.resolvers.URLPattern*]"

urlpatterns = format_suffix_patterns(urlpatterns)  

#  Argument 1 to "format_suffix_patterns" has incompatible type "List[URLPattern]"; expected "List[Union[URLResolver, RoutePattern, URLPattern, Pattern[Any]]]"

Looking at the source for format_suffix_patterns() and apply_suffix_patterns() they only iterate over the contents of the urlpatterns input, nothing specific to it being a list.

Can we change the urlpatterns parameter from List to Iterable?

from typing import Iterable

def apply_suffix_patterns(
    urlpatterns: Iterable[Union[URLResolver, RoutePattern, URLPattern, Pattern]],
    suffix_pattern: Union[str, Pattern],
    suffix_required: bool,
    suffix_route: Optional[str] = ...,
) -> List[URLPattern]: ...
def format_suffix_patterns(
    urlpatterns: Iterable[Union[URLResolver, RoutePattern, URLPattern, Pattern]],
    suffix_required: bool = ...,
    allowed: Optional[List[Union[URLPattern, Pattern, str]]] = ...,
) -> List[URLPattern]: ...

System information

  • OS: Debian GNU/Linux 11 (bullseye)
  • python version: 3.10.1
  • django version: 4.0.1
  • mypy version: 0.931
  • django-stubs version: 0.3.1
@peterschutt peterschutt added the bug Something isn't working label Jan 23, 2022
@sobolevn
Copy link
Member

PRs are welcome!

@sshishov
Copy link
Contributor

sshishov commented Jun 2, 2022

I guess the same is happening when you try to add routers.ursl to urlpatterns:

from django.urls import path
from rest_framework.routers import DefaultRouter

urlpatterns = [
    path(route="one/", view=OneView.as_view(), name="some-view"),
    ...
]
router = DefaultRouter()
router.register(prefix="two", viewset=views.TwoViewSet, basename="two")

urlpatterns += router.urls


Argument 1 to "__iadd__" of "list" has incompatible type "List[Union[URLPattern, URLResolver]]"; expected "Iterable[URLPattern]"  [arg-type]

Or it is completely different issue?

@peterschutt
Copy link
Author

peterschutt commented Jun 2, 2022

Different issue.

Mypy infers the type of your local variable urlpatterns from this line:

urlpatterns = [
    path(route="one/", view=OneView.as_view(), name="some-view"),
    ...
]

It infers it as list[URLPattern].

Give it a type when you declare it that supports URLResolver as well:

urlpatterns: list[URLPattern, URLResolver] = [
    path(route="one/", view=OneView.as_view(), name="some-view"),
    ...
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

Successfully merging a pull request may close this issue.

3 participants