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

Make from_string() and get_template() return backend-specific template #2400

Merged
merged 8 commits into from
Oct 12, 2024
6 changes: 2 additions & 4 deletions django-stubs/template/backends/base.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ from collections.abc import Iterator, Mapping
from typing import Any, Protocol, type_check_only

from django.http.request import HttpRequest
from django.template.base import Context
from django.utils.functional import cached_property
from django.utils.safestring import SafeString

class BaseEngine:
name: str
Expand All @@ -23,6 +21,6 @@ class BaseEngine:
class _EngineTemplate(Protocol):
def render(
self,
context: Context | dict[str, Any] | None = ...,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you remove this? Context can be passed to render()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the commit comment of 2a070e0: not all implementations of this render() method accept Context and the spec states that dict must be used.

The naming is a bit confusing, as there are multiple classes named Template and multiple render() methods with different interfaces. The implementer of _EngineTemplate is django.template.backends.django.Template and the render() method of that class doesn't accept Context, as it calls make_context() which explicitly rejects anything other than None and dict.

The django.template.base.Template.render() method does accept Context and in fact requires it, but that is not an implementation of the _EngineTemplate protocol, despite using the same class and method name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I got it! Thanks!

context: dict[str, Any] | None = ...,
request: HttpRequest | None = ...,
) -> SafeString: ...
) -> str: ...
2 changes: 2 additions & 0 deletions django-stubs/template/backends/django.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ from .base import BaseEngine, _EngineTemplate
class DjangoTemplates(BaseEngine):
engine: Engine
def __init__(self, params: dict[str, Any]) -> None: ...
def from_string(self, template_code: str) -> Template: ...
def get_template(self, template_name: str) -> Template: ...
def get_templatetag_libraries(self, custom_libraries: dict[str, str]) -> dict[str, str]: ...

def copy_exception(exc: TemplateDoesNotExist, backend: DjangoTemplates | None = None) -> TemplateDoesNotExist: ...
Expand Down
4 changes: 3 additions & 1 deletion django-stubs/template/backends/dummy.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ from .base import BaseEngine

class TemplateStrings(BaseEngine):
def __init__(self, params: dict[str, dict[Any, Any] | list[Any] | bool | str]) -> None: ...
def from_string(self, template_code: str) -> Template: ...
def get_template(self, template_name: str) -> Template: ...

class Template(string.Template):
template: str
def render(self, context: dict[str, str] | None = ..., request: HttpRequest | None = ...) -> str: ...
def render(self, context: dict[str, Any] | None = ..., request: HttpRequest | None = ...) -> str: ...
5 changes: 4 additions & 1 deletion django-stubs/template/backends/jinja2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ from collections.abc import Callable
from typing import Any

from _typeshed import Incomplete
from django.http.request import HttpRequest
from django.template.exceptions import TemplateSyntaxError
from django.utils.functional import cached_property

Expand All @@ -11,6 +12,8 @@ class Jinja2(BaseEngine):
env: Any
context_processors: list[str]
def __init__(self, params: dict[str, Any]) -> None: ...
def from_string(self, template_code: str) -> Template: ...
def get_template(self, template_name: str) -> Template: ...
@cached_property
def template_context_processors(self) -> list[Callable]: ...

Expand All @@ -24,6 +27,6 @@ class Template:
backend: Jinja2
origin: Origin
def __init__(self, template: Incomplete, backend: Jinja2) -> None: ...
def render(self, context: Incomplete | None = ..., request: Incomplete | None = ...) -> Incomplete: ...
def render(self, context: dict[str, Any] | None = ..., request: HttpRequest | None = ...) -> str: ...

def get_exception_info(exception: TemplateSyntaxError) -> dict[str, Any]: ...
2 changes: 1 addition & 1 deletion django-stubs/template/context.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ class RequestContext(Context):
def bind_template(self, template: Template) -> Iterator[None]: ...
def new(self, values: _ContextValues | None = None) -> RequestContext: ...

def make_context(context: Any, request: HttpRequest | None = None, **kwargs: Any) -> Context: ...
def make_context(context: dict[str, Any] | None, request: HttpRequest | None = None, **kwargs: Any) -> Context: ...
Loading