Skip to content

Commit 6ea159b

Browse files
committed
Use Sequence instead of List for path param
Unlike `List`, which is invariant, `Sequence` is covariant, which lets `path` accept lists of subsets of the `Union` as well. I believe this is safe, as django doesn't mutate this input. I found [this comment](python/mypy#3351 (comment)) helpful
1 parent cf6952c commit 6ea159b

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

django-stubs/conf/urls/__init__.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Stubs for django.conf.urls (Python 3.5)
2-
from typing import Any, Callable, Dict, List, Optional, overload, Tuple, Union
2+
from typing import Any, Callable, Dict, Optional, overload, Sequence, Tuple, Union
33

44
from django.http.response import HttpResponse, HttpResponseBase
55

@@ -10,7 +10,7 @@ handler403: Union[str, Callable[..., HttpResponse]] = ...
1010
handler404: Union[str, Callable[..., HttpResponse]] = ...
1111
handler500: Union[str, Callable[..., HttpResponse]] = ...
1212

13-
IncludedURLConf = Tuple[List[Union[URLResolver, URLPattern]], Optional[str], Optional[str]]
13+
IncludedURLConf = Tuple[Sequence[Union[URLResolver, URLPattern]], Optional[str], Optional[str]]
1414

1515
def include(arg: Any, namespace: str = ..., app_name: str = ...) -> IncludedURLConf: ...
1616
@overload
@@ -21,5 +21,5 @@ def url(
2121
def url(regex: str, view: IncludedURLConf, kwargs: Dict[str, Any] = ..., name: str = ...) -> URLResolver: ...
2222
@overload
2323
def url(
24-
regex: str, view: List[Union[URLResolver, str]], kwargs: Dict[str, Any] = ..., name: str = ...
24+
regex: str, view: Sequence[Union[URLResolver, str]], kwargs: Dict[str, Any] = ..., name: str = ...
2525
) -> URLResolver: ...

django-stubs/urls/conf.pyi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
from typing import Any, List, Optional, Tuple, overload, Callable, Dict, Union
1+
from typing import Any, Optional, Sequence, Tuple, overload, Callable, Dict, Union
22

33
from .resolvers import URLResolver, URLPattern
44
from ..conf.urls import IncludedURLConf
55
from ..http.response import HttpResponseBase
66

77
def include(
88
arg: Any, namespace: Optional[str] = ...
9-
) -> Tuple[List[Union[URLResolver, URLPattern]], Optional[str], Optional[str]]: ...
9+
) -> Tuple[Sequence[Union[URLResolver, URLPattern]], Optional[str], Optional[str]]: ...
1010

1111
# path()
1212
@overload
@@ -17,7 +17,7 @@ def path(
1717
def path(route: str, view: IncludedURLConf, kwargs: Dict[str, Any] = ..., name: str = ...) -> URLResolver: ...
1818
@overload
1919
def path(
20-
route: str, view: List[Union[URLResolver, str]], kwargs: Dict[str, Any] = ..., name: str = ...
20+
route: str, view: Sequence[Union[URLResolver, str]], kwargs: Dict[str, Any] = ..., name: str = ...
2121
) -> URLResolver: ...
2222

2323
# re_path()
@@ -29,5 +29,5 @@ def re_path(
2929
def re_path(route: str, view: IncludedURLConf, kwargs: Dict[str, Any] = ..., name: str = ...) -> URLResolver: ...
3030
@overload
3131
def re_path(
32-
route: str, view: List[Union[URLResolver, str]], kwargs: Dict[str, Any] = ..., name: str = ...
32+
route: str, view: Sequence[Union[URLResolver, str]], kwargs: Dict[str, Any] = ..., name: str = ...
3333
) -> URLResolver: ...

tests/typecheck/urls/test_conf.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@
66
def include() -> Tuple[List[Union[URLPattern, URLResolver]], None, None]: ...
77
88
path('test/', include())
9+
10+
11+
- case: test_path_accepts_pattern_resolver_union_subset
12+
main: |
13+
from typing import List, Tuple
14+
from django.urls import path, URLPattern
15+
16+
def include() -> Tuple[List[URLPattern], None, None]: ...
17+
18+
path('test/', include())

0 commit comments

Comments
 (0)