summaryrefslogtreecommitdiffhomepage
path: root/scripts/jinja2/exceptions.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/jinja2/exceptions.py')
-rw-r--r--scripts/jinja2/exceptions.py148
1 files changed, 84 insertions, 64 deletions
diff --git a/scripts/jinja2/exceptions.py b/scripts/jinja2/exceptions.py
index c9df6dc..082ebe8 100644
--- a/scripts/jinja2/exceptions.py
+++ b/scripts/jinja2/exceptions.py
@@ -1,64 +1,53 @@
-# -*- coding: utf-8 -*-
-"""
- jinja2.exceptions
- ~~~~~~~~~~~~~~~~~
+import typing as t
- Jinja exceptions.
-
- :copyright: (c) 2010 by the Jinja Team.
- :license: BSD, see LICENSE for more details.
-"""
-from jinja2._compat import imap, text_type, PY2, implements_to_string
+if t.TYPE_CHECKING:
+ from .runtime import Undefined
class TemplateError(Exception):
"""Baseclass for all template errors."""
- if PY2:
- def __init__(self, message=None):
- if message is not None:
- message = text_type(message).encode('utf-8')
- Exception.__init__(self, message)
-
- @property
- def message(self):
- if self.args:
- message = self.args[0]
- if message is not None:
- return message.decode('utf-8', 'replace')
-
- def __unicode__(self):
- return self.message or u''
- else:
- def __init__(self, message=None):
- Exception.__init__(self, message)
-
- @property
- def message(self):
- if self.args:
- message = self.args[0]
- if message is not None:
- return message
-
-
-@implements_to_string
+ def __init__(self, message: t.Optional[str] = None) -> None:
+ super().__init__(message)
+
+ @property
+ def message(self) -> t.Optional[str]:
+ return self.args[0] if self.args else None
+
+
class TemplateNotFound(IOError, LookupError, TemplateError):
- """Raised if a template does not exist."""
+ """Raised if a template does not exist.
- # looks weird, but removes the warning descriptor that just
- # bogusly warns us about message being deprecated
- message = None
+ .. versionchanged:: 2.11
+ If the given name is :class:`Undefined` and no message was
+ provided, an :exc:`UndefinedError` is raised.
+ """
+
+ # Silence the Python warning about message being deprecated since
+ # it's not valid here.
+ message: t.Optional[str] = None
+
+ def __init__(
+ self,
+ name: t.Optional[t.Union[str, "Undefined"]],
+ message: t.Optional[str] = None,
+ ) -> None:
+ IOError.__init__(self, name)
- def __init__(self, name, message=None):
- IOError.__init__(self)
if message is None:
+ from .runtime import Undefined
+
+ if isinstance(name, Undefined):
+ name._fail_with_undefined_error()
+
message = name
+
self.message = message
self.name = name
self.templates = [name]
- def __str__(self):
- return self.message
+ def __str__(self) -> str:
+ return str(self.message)
class TemplatesNotFound(TemplateNotFound):
@@ -66,54 +55,85 @@ class TemplatesNotFound(TemplateNotFound):
are selected. This is a subclass of :class:`TemplateNotFound`
exception, so just catching the base exception will catch both.
+ .. versionchanged:: 2.11
+ If a name in the list of names is :class:`Undefined`, a message
+ about it being undefined is shown rather than the empty string.
+
.. versionadded:: 2.2
"""
- def __init__(self, names=(), message=None):
+ def __init__(
+ self,
+ names: t.Sequence[t.Union[str, "Undefined"]] = (),
+ message: t.Optional[str] = None,
+ ) -> None:
if message is None:
- message = u'none of the templates given were found: ' + \
- u', '.join(imap(text_type, names))
- TemplateNotFound.__init__(self, names and names[-1] or None, message)
+ from .runtime import Undefined
+
+ parts = []
+
+ for name in names:
+ if isinstance(name, Undefined):
+ parts.append(name._undefined_message)
+ else:
+ parts.append(name)
+
+ parts_str = ", ".join(map(str, parts))
+ message = f"none of the templates given were found: {parts_str}"
+
+ super().__init__(names[-1] if names else None, message)
self.templates = list(names)
-@implements_to_string
class TemplateSyntaxError(TemplateError):
"""Raised to tell the user that there is a problem with the template."""
- def __init__(self, message, lineno, name=None, filename=None):
- TemplateError.__init__(self, message)
+ def __init__(
+ self,
+ message: str,
+ lineno: int,
+ name: t.Optional[str] = None,
+ filename: t.Optional[str] = None,
+ ) -> None:
+ super().__init__(message)
self.lineno = lineno
self.name = name
self.filename = filename
- self.source = None
+ self.source: t.Optional[str] = None
# this is set to True if the debug.translate_syntax_error
# function translated the syntax error into a new traceback
self.translated = False
- def __str__(self):
+ def __str__(self) -> str:
# for translated errors we only return the message
if self.translated:
- return self.message
+ return t.cast(str, self.message)
# otherwise attach some stuff
- location = 'line %d' % self.lineno
+ location = f"line {self.lineno}"
name = self.filename or self.name
if name:
- location = 'File "%s", %s' % (name, location)
- lines = [self.message, ' ' + location]
+ location = f'File "{name}", {location}'
+ lines = [t.cast(str, self.message), " " + location]
# if the source is set, add the line to the output
if self.source is not None:
try:
line = self.source.splitlines()[self.lineno - 1]
except IndexError:
- line = None
- if line:
- lines.append(' ' + line.strip())
-
- return u'\n'.join(lines)
+ pass
+ else:
+ lines.append(" " + line.strip())
+
+ return "\n".join(lines)
+
+ def __reduce__(self): # type: ignore
+ # https://bugs.python.org/issue1692335 Exceptions that take
+ # multiple required arguments have problems with pickling.
+ # Without this, raises TypeError: __init__() missing 1 required
+ # positional argument: 'lineno'
+ return self.__class__, (self.message, self.lineno, self.name, self.filename)
class TemplateAssertionError(TemplateSyntaxError):