1# -*- coding: utf-8 -*- 2from ._compat import imap 3from ._compat import implements_to_string 4from ._compat import PY2 5from ._compat import text_type 6 7 8class TemplateError(Exception): 9 """Baseclass for all template errors.""" 10 11 if PY2: 12 13 def __init__(self, message=None): 14 if message is not None: 15 message = text_type(message).encode("utf-8") 16 Exception.__init__(self, message) 17 18 @property 19 def message(self): 20 if self.args: 21 message = self.args[0] 22 if message is not None: 23 return message.decode("utf-8", "replace") 24 25 def __unicode__(self): 26 return self.message or u"" 27 28 else: 29 30 def __init__(self, message=None): 31 Exception.__init__(self, message) 32 33 @property 34 def message(self): 35 if self.args: 36 message = self.args[0] 37 if message is not None: 38 return message 39 40 41@implements_to_string 42class TemplateNotFound(IOError, LookupError, TemplateError): 43 """Raised if a template does not exist. 44 45 .. versionchanged:: 2.11 46 If the given name is :class:`Undefined` and no message was 47 provided, an :exc:`UndefinedError` is raised. 48 """ 49 50 # looks weird, but removes the warning descriptor that just 51 # bogusly warns us about message being deprecated 52 message = None 53 54 def __init__(self, name, message=None): 55 IOError.__init__(self, name) 56 57 if message is None: 58 from .runtime import Undefined 59 60 if isinstance(name, Undefined): 61 name._fail_with_undefined_error() 62 63 message = name 64 65 self.message = message 66 self.name = name 67 self.templates = [name] 68 69 def __str__(self): 70 return self.message 71 72 73class TemplatesNotFound(TemplateNotFound): 74 """Like :class:`TemplateNotFound` but raised if multiple templates 75 are selected. This is a subclass of :class:`TemplateNotFound` 76 exception, so just catching the base exception will catch both. 77 78 .. versionchanged:: 2.11 79 If a name in the list of names is :class:`Undefined`, a message 80 about it being undefined is shown rather than the empty string. 81 82 .. versionadded:: 2.2 83 """ 84 85 def __init__(self, names=(), message=None): 86 if message is None: 87 from .runtime import Undefined 88 89 parts = [] 90 91 for name in names: 92 if isinstance(name, Undefined): 93 parts.append(name._undefined_message) 94 else: 95 parts.append(name) 96 97 message = u"none of the templates given were found: " + u", ".join( 98 imap(text_type, parts) 99 ) 100 TemplateNotFound.__init__(self, names and names[-1] or None, message) 101 self.templates = list(names) 102 103 104@implements_to_string 105class TemplateSyntaxError(TemplateError): 106 """Raised to tell the user that there is a problem with the template.""" 107 108 def __init__(self, message, lineno, name=None, filename=None): 109 TemplateError.__init__(self, message) 110 self.lineno = lineno 111 self.name = name 112 self.filename = filename 113 self.source = None 114 115 # this is set to True if the debug.translate_syntax_error 116 # function translated the syntax error into a new traceback 117 self.translated = False 118 119 def __str__(self): 120 # for translated errors we only return the message 121 if self.translated: 122 return self.message 123 124 # otherwise attach some stuff 125 location = "line %d" % self.lineno 126 name = self.filename or self.name 127 if name: 128 location = 'File "%s", %s' % (name, location) 129 lines = [self.message, " " + location] 130 131 # if the source is set, add the line to the output 132 if self.source is not None: 133 try: 134 line = self.source.splitlines()[self.lineno - 1] 135 except IndexError: 136 line = None 137 if line: 138 lines.append(" " + line.strip()) 139 140 return u"\n".join(lines) 141 142 def __reduce__(self): 143 # https://bugs.python.org/issue1692335 Exceptions that take 144 # multiple required arguments have problems with pickling. 145 # Without this, raises TypeError: __init__() missing 1 required 146 # positional argument: 'lineno' 147 return self.__class__, (self.message, self.lineno, self.name, self.filename) 148 149 150class TemplateAssertionError(TemplateSyntaxError): 151 """Like a template syntax error, but covers cases where something in the 152 template caused an error at compile time that wasn't necessarily caused 153 by a syntax error. However it's a direct subclass of 154 :exc:`TemplateSyntaxError` and has the same attributes. 155 """ 156 157 158class TemplateRuntimeError(TemplateError): 159 """A generic runtime error in the template engine. Under some situations 160 Jinja may raise this exception. 161 """ 162 163 164class UndefinedError(TemplateRuntimeError): 165 """Raised if a template tries to operate on :class:`Undefined`.""" 166 167 168class SecurityError(TemplateRuntimeError): 169 """Raised if a template tries to do something insecure if the 170 sandbox is enabled. 171 """ 172 173 174class FilterArgumentError(TemplateRuntimeError): 175 """This error is raised if a filter was called with inappropriate 176 arguments 177 """ 178