Skip to content

Commit cb2f233

Browse files
Used _ContextKeys for context like dicts (#1298)
* Used _ContextKeys for context like dicts * Updated context like dicts to dict[_ContextKeys, Any]. * Update imports * Fix Test * Updated Imports * [pre-commit.ci] auto fixes from pre-commit.com hooks * Revert "Fix Test" This reverts commit a4b26af. * Updated dict to Mapping * [pre-commit.ci] auto fixes from pre-commit.com hooks * Removed test * Fixed flake8 errors * Imported Any Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent c3949b6 commit cb2f233

File tree

13 files changed

+66
-50
lines changed

13 files changed

+66
-50
lines changed

django-stubs/contrib/admin/options.pyi

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ from django.forms.models import (
2828
from django.forms.widgets import Media
2929
from django.http.request import HttpRequest
3030
from django.http.response import HttpResponse, HttpResponseRedirect
31+
from django.template.context import _ContextKeys
3132
from django.template.response import _TemplateForResponseT
3233
from django.urls.resolvers import URLPattern
3334
from django.utils.datastructures import _ListOrTuple
@@ -231,7 +232,7 @@ class ModelAdmin(BaseModelAdmin[_ModelT]):
231232
def render_change_form(
232233
self,
233234
request: HttpRequest,
234-
context: dict[str, Any],
235+
context: Mapping[_ContextKeys, Any],
235236
add: bool = ...,
236237
change: bool = ...,
237238
form_url: str = ...,
@@ -244,7 +245,7 @@ class ModelAdmin(BaseModelAdmin[_ModelT]):
244245
# Probably FileResponse cannot come from ModelAdmin views
245246
def response_action(self, request: HttpRequest, queryset: QuerySet) -> HttpResponse | None: ...
246247
def response_delete(self, request: HttpRequest, obj_display: str, obj_id: int) -> HttpResponse: ...
247-
def render_delete_form(self, request: HttpRequest, context: dict[str, Any]) -> HttpResponse: ...
248+
def render_delete_form(self, request: HttpRequest, context: Mapping[_ContextKeys, Any]) -> HttpResponse: ...
248249
def get_inline_formsets(
249250
self, request: HttpRequest, formsets: list[Any], inline_instances: list[Any], obj: _ModelT | None = ...
250251
) -> list[Any]: ...
@@ -254,23 +255,29 @@ class ModelAdmin(BaseModelAdmin[_ModelT]):
254255
request: HttpRequest,
255256
object_id: str | None = ...,
256257
form_url: str = ...,
257-
extra_context: dict[str, Any] | None = ...,
258+
extra_context: Mapping[_ContextKeys, Any] | None = ...,
258259
) -> HttpResponse: ...
259260
def add_view(
260-
self, request: HttpRequest, form_url: str = ..., extra_context: dict[str, Any] | None = ...
261+
self, request: HttpRequest, form_url: str = ..., extra_context: Mapping[_ContextKeys, Any] | None = ...
261262
) -> HttpResponse: ...
262263
def change_view(
263-
self, request: HttpRequest, object_id: str, form_url: str = ..., extra_context: dict[str, Any] | None = ...
264+
self,
265+
request: HttpRequest,
266+
object_id: str,
267+
form_url: str = ...,
268+
extra_context: Mapping[_ContextKeys, Any] | None = ...,
269+
) -> HttpResponse: ...
270+
def changelist_view(
271+
self, request: HttpRequest, extra_context: Mapping[_ContextKeys, Any] | None = ...
264272
) -> HttpResponse: ...
265-
def changelist_view(self, request: HttpRequest, extra_context: dict[str, Any] | None = ...) -> HttpResponse: ...
266273
def get_deleted_objects(
267274
self, objs: Sequence[_ModelT] | QuerySet[_ModelT], request: HttpRequest
268275
) -> tuple[list[Model], dict[str, int], set[str], list[str]]: ...
269276
def delete_view(
270-
self, request: HttpRequest, object_id: str, extra_context: dict[str, Any] | None = ...
277+
self, request: HttpRequest, object_id: str, extra_context: Mapping[_ContextKeys, Any] | None = ...
271278
) -> HttpResponse: ...
272279
def history_view(
273-
self, request: HttpRequest, object_id: str, extra_context: dict[str, Any] | None = ...
280+
self, request: HttpRequest, object_id: str, extra_context: Mapping[_ContextKeys, Any] | None = ...
274281
) -> HttpResponse: ...
275282

276283
_ChildModelT = TypeVar("_ChildModelT", bound=Model)

django-stubs/contrib/admin/sites.pyi

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sys
2-
from collections.abc import Callable, Iterable
2+
from collections.abc import Callable, Iterable, Mapping
33
from typing import Any
44

55
from django.apps.config import AppConfig
@@ -10,6 +10,7 @@ from django.db.models.base import Model
1010
from django.db.models.query import QuerySet
1111
from django.http.request import HttpRequest
1212
from django.http.response import HttpResponse
13+
from django.template.context import _ContextKeys
1314
from django.template.response import TemplateResponse
1415
from django.urls import URLPattern, URLResolver
1516
from django.utils.functional import LazyObject, _StrOrPromise
@@ -70,18 +71,26 @@ class AdminSite:
7071
@property
7172
def urls(self) -> tuple[list[URLResolver | URLPattern], str, str]: ...
7273
def each_context(self, request: HttpRequest) -> dict[str, Any]: ...
73-
def password_change(self, request: HttpRequest, extra_context: dict[str, Any] | None = ...) -> TemplateResponse: ...
74+
def password_change(
75+
self, request: HttpRequest, extra_context: Mapping[_ContextKeys, Any] | None = ...
76+
) -> TemplateResponse: ...
7477
def password_change_done(
75-
self, request: HttpRequest, extra_context: dict[str, Any] | None = ...
78+
self, request: HttpRequest, extra_context: Mapping[_ContextKeys, Any] | None = ...
79+
) -> TemplateResponse: ...
80+
def i18n_javascript(
81+
self, request: HttpRequest, extra_context: Mapping[_ContextKeys, Any] | None = ...
82+
) -> HttpResponse: ...
83+
def logout(
84+
self, request: HttpRequest, extra_context: Mapping[_ContextKeys, Any] | None = ...
7685
) -> TemplateResponse: ...
77-
def i18n_javascript(self, request: HttpRequest, extra_context: dict[str, Any] | None = ...) -> HttpResponse: ...
78-
def logout(self, request: HttpRequest, extra_context: dict[str, Any] | None = ...) -> TemplateResponse: ...
79-
def login(self, request: HttpRequest, extra_context: dict[str, Any] | None = ...) -> HttpResponse: ...
86+
def login(self, request: HttpRequest, extra_context: Mapping[_ContextKeys, Any] | None = ...) -> HttpResponse: ...
8087
def _build_app_dict(self, request: HttpRequest, label: _StrOrPromise | None = ...) -> dict[str, Any]: ...
8188
def get_app_list(self, request: HttpRequest) -> list[Any]: ...
82-
def index(self, request: HttpRequest, extra_context: dict[str, Any] | None = ...) -> TemplateResponse: ...
89+
def index(
90+
self, request: HttpRequest, extra_context: Mapping[_ContextKeys, Any] | None = ...
91+
) -> TemplateResponse: ...
8392
def app_index(
84-
self, request: HttpRequest, app_label: str, extra_context: dict[str, Any] | None = ...
93+
self, request: HttpRequest, app_label: str, extra_context: Mapping[_ContextKeys, Any] | None = ...
8594
) -> TemplateResponse: ...
8695
def autocomplete_view(self, request: HttpRequest) -> HttpResponse: ...
8796
def catch_all_view(self, request: HttpRequest, url: str) -> HttpResponse: ...

django-stubs/forms/renderers.pyi

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
from collections.abc import Mapping
12
from typing import Any
23

34
from django.http import HttpRequest
45
from django.template.backends.base import BaseEngine
56
from django.template.backends.django import DjangoTemplates as DjangoTemplatesR
67
from django.template.backends.jinja2 import Jinja2 as Jinja2R
78
from django.template.base import Template
9+
from django.template.context import _ContextKeys
810

911
def get_default_renderer() -> BaseRenderer: ...
1012

1113
class BaseRenderer:
1214
def get_template(self, template_name: str) -> Any: ...
13-
def render(self, template_name: str, context: dict[str, Any], request: HttpRequest | None = ...) -> str: ...
15+
def render(
16+
self, template_name: str, context: Mapping[_ContextKeys, Any], request: HttpRequest | None = ...
17+
) -> str: ...
1418

1519
class EngineMixin:
1620
def get_template(self, template_name: str) -> Any: ...

django-stubs/shortcuts.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ from django.http import HttpRequest
77
from django.http.response import HttpResponse as HttpResponse
88
from django.http.response import HttpResponsePermanentRedirect as HttpResponsePermanentRedirect
99
from django.http.response import HttpResponseRedirect as HttpResponseRedirect
10+
from django.template.context import _ContextKeys
1011
from typing_extensions import Literal
1112

1213
def render(
1314
request: HttpRequest,
1415
template_name: str | Sequence[str],
15-
context: Mapping[str, Any] | None = ...,
16+
context: Mapping[_ContextKeys, Any] | None = ...,
1617
content_type: str | None = ...,
1718
status: int | None = ...,
1819
using: str | None = ...,

django-stubs/template/backends/base.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ from typing import Any, Protocol
44
from django.http.request import HttpRequest
55
from django.template import TemplateDoesNotExist
66
from django.template.base import Context
7+
from django.template.context import _ContextKeys
78
from django.utils.safestring import SafeString
89

910
class BaseEngine:
@@ -22,6 +23,6 @@ class BaseEngine:
2223
class _EngineTemplate(Protocol):
2324
def render(
2425
self,
25-
context: Context | dict[str, Any] | None = ...,
26+
context: Context | Mapping[_ContextKeys, Any] | None = ...,
2627
request: HttpRequest | None = ...,
2728
) -> SafeString: ...

django-stubs/template/backends/dummy.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import string
2+
from collections.abc import Mapping
23
from typing import Any
34

45
from django.http.request import HttpRequest
6+
from django.template.context import _ContextKeys
57

68
from .base import BaseEngine
79

@@ -11,4 +13,4 @@ class TemplateStrings(BaseEngine):
1113

1214
class Template(string.Template):
1315
template: str
14-
def render(self, context: dict[str, str] | None = ..., request: HttpRequest | None = ...) -> str: ...
16+
def render(self, context: Mapping[_ContextKeys, Any] | None = ..., request: HttpRequest | None = ...) -> str: ...

django-stubs/template/base.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ from re import Pattern
55
from typing import Any
66

77
from django.template.context import Context as Context
8+
from django.template.context import _ContextKeys
89
from django.template.engine import Engine
910
from django.template.library import Library
1011
from django.template.loaders.base import Loader
@@ -59,7 +60,7 @@ class Template:
5960
engine: Engine | None = ...,
6061
) -> None: ...
6162
def __iter__(self) -> Iterator[Node]: ...
62-
def render(self, context: Context | dict[str, Any] | None) -> SafeString: ...
63+
def render(self, context: Context | Mapping[_ContextKeys, Any] | None) -> SafeString: ...
6364
def compile_nodelist(self) -> NodeList: ...
6465
def get_exception_info(self, exception: Exception, token: Token) -> dict[str, Any]: ...
6566

@@ -138,7 +139,7 @@ class Variable:
138139
translate: bool
139140
message_context: str | None
140141
def __init__(self, var: dict[Any, Any] | str) -> None: ...
141-
def resolve(self, context: Mapping[str, Mapping[str, Any]] | Context | int | str) -> Any: ...
142+
def resolve(self, context: Mapping[_ContextKeys, Any] | Context | int | str) -> Any: ...
142143

143144
class Node:
144145
must_be_first: bool

django-stubs/template/context.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from collections.abc import Callable, Iterable, Iterator
1+
from collections.abc import Callable, Iterable, Iterator, Mapping
22
from contextlib import contextmanager
33
from types import TracebackType
44
from typing import Any, TypeVar
@@ -40,7 +40,7 @@ class BaseContext(Iterable[Any]):
4040
def get(self, key: _ContextKeys, otherwise: Any | None = ...) -> Any | None: ...
4141
def setdefault(self, key: _ContextKeys, default: list[Origin] | int | None = ...) -> list[Origin] | int | None: ...
4242
def new(self, values: _ContextValues | None = ...) -> Context: ...
43-
def flatten(self) -> dict[_ContextKeys, dict[_ContextKeys, type[Any] | str] | int | str | None]: ...
43+
def flatten(self) -> Mapping[_ContextKeys, Any]: ...
4444

4545
class Context(BaseContext):
4646
dicts: Any
@@ -55,7 +55,7 @@ class Context(BaseContext):
5555
) -> None: ...
5656
@contextmanager
5757
def bind_template(self, template: Template) -> Iterator[None]: ...
58-
def update(self, other_dict: dict[str, Any] | Context) -> ContextDict: ...
58+
def update(self, other_dict: Mapping[_ContextKeys, Any] | Context) -> ContextDict: ...
5959

6060
class RenderContext(BaseContext):
6161
dicts: list[dict[IncludeNode | str, str]]

django-stubs/template/defaulttags.pyi

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from collections import namedtuple
2-
from collections.abc import Iterator, Sequence
2+
from collections.abc import Iterator, Mapping, Sequence
33
from datetime import date as real_date
44
from typing import Any
55

@@ -8,6 +8,7 @@ from django.template.context import Context
88
from django.utils.safestring import SafeString
99

1010
from .base import Node, NodeList
11+
from .context import _ContextKeys
1112
from .library import Library
1213
from .smartif import IfParser, Literal
1314

@@ -154,13 +155,13 @@ class WidthRatioNode(Node):
154155

155156
class WithNode(Node):
156157
nodelist: NodeList
157-
extra_context: dict[str, Any]
158+
extra_context: Mapping[_ContextKeys, Any]
158159
def __init__(
159160
self,
160161
var: str | None,
161162
name: str | None,
162163
nodelist: NodeList | Sequence[Node],
163-
extra_context: dict[str, Any] | None = ...,
164+
extra_context: Mapping[_ContextKeys, Any] | None = ...,
164165
) -> None: ...
165166

166167
def autoescape(parser: Parser, token: Token) -> AutoEscapeControlNode: ...

django-stubs/template/engine.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from collections.abc import Callable, Sequence
1+
from collections.abc import Callable, Mapping, Sequence
22
from typing import Any
33

44
from django.template.base import Origin
@@ -8,6 +8,7 @@ from django.utils.safestring import SafeString
88
from typing_extensions import TypeAlias
99

1010
from .base import Template
11+
from .context import _ContextKeys
1112

1213
_Loader: TypeAlias = Any
1314

@@ -53,5 +54,5 @@ class Engine:
5354
) -> tuple[Template, Origin]: ...
5455
def from_string(self, template_code: str) -> Template: ...
5556
def get_template(self, template_name: str) -> Template: ...
56-
def render_to_string(self, template_name: str, context: dict[str, Any] | None = ...) -> SafeString: ...
57+
def render_to_string(self, template_name: str, context: Mapping[_ContextKeys, Any] | None = ...) -> SafeString: ...
5758
def select_template(self, template_name_list: list[str]) -> Template: ...

django-stubs/template/loader.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ from django.utils.safestring import SafeString
77

88
from . import engines as engines # noqa: F401
99
from .backends.base import _EngineTemplate
10+
from .context import _ContextKeys
1011

1112
def get_template(template_name: str, using: str | None = ...) -> _EngineTemplate: ...
1213
def select_template(template_name_list: Sequence[str] | str, using: str | None = ...) -> Any: ...
1314
def render_to_string(
1415
template_name: Sequence[str] | str,
15-
context: Mapping[str, Any] | None = ...,
16+
context: Mapping[_ContextKeys, Any] | None = ...,
1617
request: HttpRequest | None = ...,
1718
using: str | None = ...,
1819
) -> SafeString: ...

django-stubs/template/response.pyi

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import functools
2-
from collections.abc import Callable, Iterator, Sequence
2+
from collections.abc import Callable, Iterator, Mapping, Sequence
33
from http.cookies import SimpleCookie
44
from typing import Any, Union # noqa: Y037 # https://github.com/python/mypy/issues/12211
55

66
from django.core.handlers.wsgi import WSGIRequest
77
from django.http import HttpResponse
88
from django.http.request import HttpRequest
99
from django.template.base import Template
10-
from django.template.context import RequestContext
10+
from django.template.context import RequestContext, _ContextKeys
1111
from django.test.client import Client
1212
from django.utils.datastructures import _ListOrTuple
1313
from typing_extensions import TypeAlias
@@ -24,20 +24,20 @@ class SimpleTemplateResponse(HttpResponse):
2424
status_code: int
2525
rendering_attrs: Any
2626
template_name: _TemplateForResponseT
27-
context_data: dict[str, Any] | None
27+
context_data: Mapping[_ContextKeys, Any] | None
2828
using: str | None
2929
def __init__(
3030
self,
3131
template: _TemplateForResponseT,
32-
context: dict[str, Any] | None = ...,
32+
context: Mapping[_ContextKeys, Any] | None = ...,
3333
content_type: str | None = ...,
3434
status: int | None = ...,
3535
charset: str | None = ...,
3636
using: str | None = ...,
3737
headers: dict[str, Any] | None = ...,
3838
) -> None: ...
3939
def resolve_template(self, template: Sequence[str] | Template | str) -> Template: ...
40-
def resolve_context(self, context: dict[str, Any] | None) -> dict[str, Any] | None: ...
40+
def resolve_context(self, context: Mapping[_ContextKeys, Any] | None) -> Mapping[_ContextKeys, Any] | None: ...
4141
@property
4242
def rendered_content(self) -> str: ...
4343
def add_post_render_callback(self, callback: Callable) -> None: ...
@@ -50,7 +50,7 @@ class TemplateResponse(SimpleTemplateResponse):
5050
client: Client
5151
closed: bool
5252
context: RequestContext
53-
context_data: dict[str, Any] | None
53+
context_data: Mapping[_ContextKeys, Any] | None
5454
cookies: SimpleCookie[str]
5555
csrf_cookie_set: bool
5656
json: functools.partial
@@ -65,7 +65,7 @@ class TemplateResponse(SimpleTemplateResponse):
6565
self,
6666
request: HttpRequest,
6767
template: _TemplateForResponseT,
68-
context: dict[str, Any] | None = ...,
68+
context: Mapping[_ContextKeys, Any] | None = ...,
6969
content_type: str | None = ...,
7070
status: int | None = ...,
7171
charset: str | None = ...,

tests/typecheck/test_shortcuts.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,6 @@
3737
class MyUser(models.Model):
3838
pass
3939
40-
- case: check_render_function_arguments_annotations
41-
main: |
42-
from typing import Any
43-
from typing_extensions import TypedDict
44-
from django.shortcuts import render
45-
from django.http.request import HttpRequest
46-
47-
TestContext = TypedDict("TestContext", {"user": Any})
48-
test_context: TestContext = {"user": "test"}
49-
reveal_type(test_context) # N: Revealed type is "TypedDict('main.TestContext', {'user': Any})"
50-
reveal_type(render(HttpRequest(), '', test_context)) # N: Revealed type is "django.http.response.HttpResponse"
51-
5240
- case: check_redirect_return_annotation
5341
main: |
5442
from django.shortcuts import redirect

0 commit comments

Comments
 (0)