updates
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
"""The runtime functions and state used by compiled templates."""
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import typing as t
|
||||
@@ -28,7 +29,9 @@ F = t.TypeVar("F", bound=t.Callable[..., t.Any])
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
import logging
|
||||
|
||||
import typing_extensions as te
|
||||
|
||||
from .environment import Environment
|
||||
|
||||
class LoopRenderFunc(te.Protocol):
|
||||
@@ -37,8 +40,7 @@ if t.TYPE_CHECKING:
|
||||
reciter: t.Iterable[V],
|
||||
loop_render_func: "LoopRenderFunc",
|
||||
depth: int = 0,
|
||||
) -> str:
|
||||
...
|
||||
) -> str: ...
|
||||
|
||||
|
||||
# these variables are exported to the template runtime
|
||||
@@ -170,7 +172,7 @@ class Context:
|
||||
):
|
||||
self.parent = parent
|
||||
self.vars: t.Dict[str, t.Any] = {}
|
||||
self.environment: "Environment" = environment
|
||||
self.environment: Environment = environment
|
||||
self.eval_ctx = EvalContext(self.environment, name)
|
||||
self.exported_vars: t.Set[str] = set()
|
||||
self.name = name
|
||||
@@ -259,7 +261,10 @@ class Context:
|
||||
|
||||
@internalcode
|
||||
def call(
|
||||
__self, __obj: t.Callable, *args: t.Any, **kwargs: t.Any # noqa: B902
|
||||
__self,
|
||||
__obj: t.Callable[..., t.Any],
|
||||
*args: t.Any,
|
||||
**kwargs: t.Any, # noqa: B902
|
||||
) -> t.Union[t.Any, "Undefined"]:
|
||||
"""Call the callable with the arguments and keyword arguments
|
||||
provided but inject the active context or environment as first
|
||||
@@ -272,9 +277,9 @@ class Context:
|
||||
# Allow callable classes to take a context
|
||||
if (
|
||||
hasattr(__obj, "__call__") # noqa: B004
|
||||
and _PassArg.from_obj(__obj.__call__) is not None # type: ignore
|
||||
and _PassArg.from_obj(__obj.__call__) is not None
|
||||
):
|
||||
__obj = __obj.__call__ # type: ignore
|
||||
__obj = __obj.__call__
|
||||
|
||||
pass_arg = _PassArg.from_obj(__obj)
|
||||
|
||||
@@ -362,7 +367,7 @@ class BlockReference:
|
||||
|
||||
@internalcode
|
||||
async def _async_call(self) -> str:
|
||||
rv = concat(
|
||||
rv = self._context.environment.concat( # type: ignore
|
||||
[x async for x in self._stack[self._depth](self._context)] # type: ignore
|
||||
)
|
||||
|
||||
@@ -376,7 +381,9 @@ class BlockReference:
|
||||
if self._context.environment.is_async:
|
||||
return self._async_call() # type: ignore
|
||||
|
||||
rv = concat(self._stack[self._depth](self._context))
|
||||
rv = self._context.environment.concat( # type: ignore
|
||||
self._stack[self._depth](self._context)
|
||||
)
|
||||
|
||||
if self._context.eval_ctx.autoescape:
|
||||
return Markup(rv)
|
||||
@@ -586,7 +593,7 @@ class AsyncLoopContext(LoopContext):
|
||||
|
||||
@staticmethod
|
||||
def _to_iterator( # type: ignore
|
||||
iterable: t.Union[t.Iterable[V], t.AsyncIterable[V]]
|
||||
iterable: t.Union[t.Iterable[V], t.AsyncIterable[V]],
|
||||
) -> t.AsyncIterator[V]:
|
||||
return auto_aiter(iterable)
|
||||
|
||||
@@ -787,8 +794,8 @@ class Macro:
|
||||
|
||||
|
||||
class Undefined:
|
||||
"""The default undefined type. This undefined type can be printed and
|
||||
iterated over, but every other access will raise an :exc:`UndefinedError`:
|
||||
"""The default undefined type. This can be printed, iterated, and treated as
|
||||
a boolean. Any other operation will raise an :exc:`UndefinedError`.
|
||||
|
||||
>>> foo = Undefined(name='foo')
|
||||
>>> str(foo)
|
||||
@@ -853,7 +860,11 @@ class Undefined:
|
||||
|
||||
@internalcode
|
||||
def __getattr__(self, name: str) -> t.Any:
|
||||
if name[:2] == "__":
|
||||
# Raise AttributeError on requests for names that appear to be unimplemented
|
||||
# dunder methods to keep Python's internal protocol probing behaviors working
|
||||
# properly in cases where another exception type could cause unexpected or
|
||||
# difficult-to-diagnose failures.
|
||||
if name[:2] == "__" and name[-2:] == "__":
|
||||
raise AttributeError(name)
|
||||
|
||||
return self._fail_with_undefined_error()
|
||||
@@ -927,9 +938,7 @@ def make_logging_undefined(
|
||||
logger.addHandler(logging.StreamHandler(sys.stderr))
|
||||
|
||||
def _log_message(undef: Undefined) -> None:
|
||||
logger.warning( # type: ignore
|
||||
"Template variable warning: %s", undef._undefined_message
|
||||
)
|
||||
logger.warning("Template variable warning: %s", undef._undefined_message)
|
||||
|
||||
class LoggingUndefined(base): # type: ignore
|
||||
__slots__ = ()
|
||||
@@ -979,10 +988,20 @@ class ChainableUndefined(Undefined):
|
||||
def __html__(self) -> str:
|
||||
return str(self)
|
||||
|
||||
def __getattr__(self, _: str) -> "ChainableUndefined":
|
||||
def __getattr__(self, name: str) -> "ChainableUndefined":
|
||||
# Raise AttributeError on requests for names that appear to be unimplemented
|
||||
# dunder methods to avoid confusing Python with truthy non-method objects that
|
||||
# do not implement the protocol being probed for. e.g., copy.copy(Undefined())
|
||||
# fails spectacularly if getattr(Undefined(), '__setstate__') returns an
|
||||
# Undefined object instead of raising AttributeError to signal that it does not
|
||||
# support that style of object initialization.
|
||||
if name[:2] == "__" and name[-2:] == "__":
|
||||
raise AttributeError(name)
|
||||
|
||||
return self
|
||||
|
||||
__getitem__ = __getattr__ # type: ignore
|
||||
def __getitem__(self, _name: str) -> "ChainableUndefined": # type: ignore[override]
|
||||
return self
|
||||
|
||||
|
||||
class DebugUndefined(Undefined):
|
||||
@@ -1041,13 +1060,3 @@ class StrictUndefined(Undefined):
|
||||
__iter__ = __str__ = __len__ = Undefined._fail_with_undefined_error
|
||||
__eq__ = __ne__ = __bool__ = __hash__ = Undefined._fail_with_undefined_error
|
||||
__contains__ = Undefined._fail_with_undefined_error
|
||||
|
||||
|
||||
# Remove slots attributes, after the metaclass is applied they are
|
||||
# unneeded and contain wrong data for subclasses.
|
||||
del (
|
||||
Undefined.__slots__,
|
||||
ChainableUndefined.__slots__,
|
||||
DebugUndefined.__slots__,
|
||||
StrictUndefined.__slots__,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user