def parse(self, parser): lineno = next(parser.stream).lineno next_token = parser.stream.look() # if there are parameters if next_token.type == "comma": args = [parser.parse_expression()] if parser.stream.skip_if('comma'): args.append(parser.parse_expression()) else: raise TemplateSyntaxError("Missing Lorem Ipsum generator parameter: kind", lineno) if args[1].value not in self.GENERATORS: raise TemplateSyntaxError( "Supported Lorem Ipsum generator kinds are: %s" % ", ".join(self.GENERATORS.keys()), lineno ) else: # if no parameters were supplied args = [nodes.Const(1), nodes.Const("paragraphs")] return nodes.Output( [self.call_method("_lipsum", args)], lineno=lineno )
def parse(self, parser): # Store the first lineno for the actual function call lineno = parser.stream.current.lineno next(parser.stream) args = [] kindarg = const(parser.parse_expression()) if kindarg.value in self.compressors: args.append(kindarg) else: raise TemplateSyntaxError( 'Compress kind may be one of: %r, got: %r' % (self.compressors.keys(), kindarg.value), parser.stream.current.lineno) # For legacy support, allow for a commma but simply ignore it parser.stream.skip_if('comma') # Some sane defaults for file output namearg = nodes.Const(None) modearg = nodes.Const('file') # If we're not at the "%}" part yet we must have a output mode argument if parser.stream.current.type != 'block_end': modearg = const(parser.parse_expression()) args.append(modearg) if modearg.value == compress.OUTPUT_FILE: # The file mode optionally accepts a name if parser.stream.current.type != 'block_end': namearg = const(parser.parse_expression()) elif modearg.value == compress.OUTPUT_INLINE or modearg.value == compress.OUTPUT_PRELOAD: pass else: raise TemplateSyntaxError( 'Compress mode may be one of: %r, got %r' % (compress.OUTPUT_MODES, modearg.value), parser.stream.current.lineno) # Parse everything between the compress and endcompress tags body = parser.parse_statements(['name:endcompress'], drop_needle=True) # Skip the kind if used in the endblock, by using the kind in the # endblock the templates are slightly more readable. parser.stream.skip_if('name:' + kindarg.value) return nodes.CallBlock( self.call_method('_compress_normal', [kindarg, modearg, namearg]), [], [], body).set_lineno(lineno)
def _save_compound(self, compound, system_name, forcefield, ast_node, caller): import mbuild as mb if isinstance(compound, mb.Compound): system_name = os.path.join(self.environment.globals['output_dir'], system_name) mkdirs.mkdirs(system_name, exists_ok=True) compound.save(system_name, forcefield=forcefield, overwrite=True) else: if isinstance(compound, string_types) and re.match(r'^\s*\{\{\s*\w+\s*\}\}\s*$', compound, 0): raise TemplateSyntaxError("Context is not an mBuild Compound, but '{}'".format(compound), lineno=0) else: raise TemplateSyntaxError("Context is not an mBuild Compound, but of type {}".format(type(compound)), lineno=0) return ''
def expect(self, expr): if not self.current.test(expr): expr = describe_token_expr(expr) if self.current.type is TOKEN_EOF: raise TemplateSyntaxError( 'unexpected end of template, expected %r.' % expr, self.current.lineno, self.name, self.filename) raise TemplateSyntaxError( 'expected token %r, got %r' % (expr, describe_token(self.current)), self.current.lineno, self.name, self.filename) try: return self.current finally: next(self)
def parse_formrow(self, parser, tag): lineno = tag.lineno field = parser.parse_expression() template_name = None if not parser.stream.current.test('block_end'): template_name = parser.parse_expression() else: template_name = nodes.Call( nodes.Name('get_formrow_template', 'load'), [], [ nodes.Keyword('caller_template', nodes.Const(parser.name)), nodes.Keyword('form', nodes.Name('form_utils_form', 'load')) ], None, None, ) if not parser.stream.current.test('block_end'): raise TemplateSyntaxError("Too many arguments", lineno) node = nodes.Scope(lineno=lineno) assignments = [nodes.Assign(nodes.Name('field', 'store'), field)] node.body = assignments + [ nodes.Include(template_name, True, False) ] return node.set_lineno(lineno)
def parse(self, parser): lineno = next(parser.stream).lineno kindarg = parser.parse_expression() # Allow kind to be defined as jinja2 name node if isinstance(kindarg, nodes.Name): kindarg = nodes.Const(kindarg.name) args = [kindarg] if args[0].value not in self.compressors: raise TemplateSyntaxError( "compress kind may be one of: %s" % (", ".join(self.compressors.keys())), lineno, ) if parser.stream.skip_if("comma"): modearg = parser.parse_expression() # Allow mode to be defined as jinja2 name node if isinstance(modearg, nodes.Name): modearg = nodes.Const(modearg.name) args.append(modearg) else: args.append(nodes.Const("file")) body = parser.parse_statements(["name:endcompress"], drop_needle=True) # Skip the kind if used in the endblock, by using the kind in the # endblock the templates are slightly more readable. parser.stream.skip_if("name:" + kindarg.value) return nodes.CallBlock(self.call_method("_compress_normal", args), [], [], body).set_lineno(lineno)
def parse(self, parser): lineno = parser.stream.__next__().lineno value = parser.parse_expression() items_per_page_obj = parser.stream.next_if('integer') items_per_page = items_per_page_obj.value if items_per_page_obj else DEFAULT_PAGINATION if parser.stream.skip_if('name:as'): name = parser.stream.expect('name').value elif hasattr(value, 'name'): name = value.name else: raise TemplateSyntaxError("Cannot determine the name of objects you want to paginate, use 'as foobar' syntax", lineno) while not parser.stream.current.type == 'block_end': parser.stream.skip() return [ nodes.Assign(nodes.Name(name + '_pages', 'store'), self.call_method('_render_pages', [value, nodes.Name('request', 'load'), nodes.Const(items_per_page)]) ).set_lineno(lineno), nodes.Assign(nodes.Name(name, 'store'), nodes.Getattr(nodes.Name(name + '_pages', 'load'), 'object_list', nodes.Impossible()) ).set_lineno(lineno), ]
def expect(self, expr): """Expect a given token type and return it. This accepts the same argument as :meth:`jinja2.lexer.Token.test`. """ if not self.current.test(expr): expr = describe_token_expr(expr) if self.current.type is TOKEN_EOF: raise TemplateSyntaxError( 'unexpected end of template, expected %r.' % expr, self.current.lineno, self.name, self.filename) raise TemplateSyntaxError( 'expected token %r, got %r' % (expr, describe_token(self.current)), self.current.lineno, self.name, self.filename) try: return self.current finally: next(self)
def parse(self, parser): lineno = parser.stream.next().lineno object_list = parser.parse_expression() if parser.stream.skip_if('name:as'): name = parser.stream.expect('name').value elif hasattr(object_list, 'name'): name = object_list.name else: raise TemplateSyntaxError( "Cannot determine the name of objects " \ "you want to paginate, use 'as foobar' syntax", lineno) kwargs = [] # wait... what? loops = 0 while parser.stream.current.type != 'block_end': lineno = parser.stream.current.lineno if loops: parser.stream.expect('comma') key = parser.parse_assign_target().name if key not in self.default_kwargs.keys(): raise TemplateSyntaxError( "Unknown keyword argument for autopaginate. "\ "Your options are: %s" % ( ", ".join(self.default_kwargs.keys()) )) parser.stream.expect('assign') value = parser.parse_expression() kwargs.append(nodes.Keyword(key, value)) loops += 1 return [ nodes.Assign(nodes.Name(name + '_pages', 'store'), self.call_method('_render_pages', [object_list, nodes.Name('request', 'load')], kwargs) ).set_lineno(lineno), nodes.Assign(nodes.Name(name, 'store'), nodes.Getattr(nodes.Name(name + '_pages', 'load'), 'object_list', nodes.Impossible()) ).set_lineno(lineno), ]
def expect(self, expr): """Expect a given token type and return it. This accepts the same argument as :meth:`jinja2.lexer.Token.test`. """ if not self.current.test(expr): if ':' in expr: expr = expr.split(':')[1] if self.current.type is TOKEN_EOF: raise TemplateSyntaxError( 'unexpected end of template, ' 'expected %r.' % expr, self.current.lineno, self.name, self.filename) raise TemplateSyntaxError( "expected token %r, got %r" % (expr, str(self.current)), self.current.lineno, self.name, self.filename) try: return self.current finally: self.next()
def parse_formrow_template(self, parser, tag): lineno = tag.lineno template_name = parser.parse_expression() if not parser.stream.current.test('block_end'): raise TemplateSyntaxError("Too many arguments", lineno) call = self.call_method('_process', [ template_name, nodes.Name('form_utils_form', 'load', lineno=lineno) ]) return nodes.Output([nodes.MarkSafe(call)]).set_lineno(lineno)
def wrap(self, stream, name=None, filename=None): """This is called with the stream as returned by `tokenize` and wraps every token in a :class:`Token` and converts the value. """ for lineno, token, value in stream: if token in ignored_tokens: continue elif token == "linestatement_begin": token = "block_begin" elif token == "linestatement_end": token = "block_end" # we are not interested in those tokens in the parser elif token in ("raw_begin", "raw_end"): continue elif token == "data": value = self._normalize_newlines(value) elif token == "keyword": token = value elif token == "name": value = str(value) if check_ident and not value.isidentifier(): raise TemplateSyntaxError( "Invalid character in identifier", lineno, name, filename ) elif token == "string": # try to unescape string try: value = ( self._normalize_newlines(value[1:-1]) .encode("ascii", "backslashreplace") .decode("unicode-escape") ) except Exception as e: msg = str(e).split(":")[-1].strip() raise TemplateSyntaxError(msg, lineno, name, filename) elif token == "integer": value = int(value) elif token == "float": value = float(value) elif token == "operator": token = operators[value] yield Token(lineno, token, value)
def parse(self, parser): stream = parser.stream tag = stream.next() # get view name if stream.current.test('string'): viewname = parser.parse_primary() else: # parse valid tokens and manually build a string from them bits = [] name_allowed = True while True: if stream.current.test_any('dot', 'sub'): bits.append(stream.next()) name_allowed = True elif stream.current.test('name') and name_allowed: bits.append(stream.next()) name_allowed = False else: break viewname = nodes.Const("".join([b.value for b in bits])) if not bits: raise TemplateSyntaxError( "'%s' requires path to view" % tag.value, tag.lineno) # get arguments args = [] kwargs = [] while not stream.current.test_any('block_end', 'name:as'): if args or kwargs: stream.expect('comma') if stream.current.test('name') and stream.look().test('assign'): key = nodes.Const(stream.next().value) stream.skip() value = parser.parse_expression() kwargs.append(nodes.Pair(key, value, lineno=key.lineno)) else: args.append(parser.parse_expression()) make_call_node = lambda *kw: \ self.call_method('_reverse', args=[viewname, nodes.List(args), nodes.Dict(kwargs)], kwargs=kw) # if an as-clause is specified, write the result to context... if stream.next_if('name:as'): var = nodes.Name(stream.expect('name').value, 'store') call_node = make_call_node( nodes.Keyword('fail', nodes.Const(False))) return nodes.Assign(var, call_node) # ...otherwise print it out. else: return nodes.Output([make_call_node()]).set_lineno(tag.lineno)
def json_path(data, path): if data is None: raise TemplateSyntaxError('JSON decode failure!', 0) jsonpath_expr = jsonpath_parse(path) match = jsonpath_expr.find(data) if len(match) < 1: return '' value = match[0].value if value is None: value = 'null' return value
def wrap(self, stream, name=None, filename=None): """This is called with the stream as returned by `tokenize` and wraps every token in a :class:`Token` and converts the value. """ for lineno, token, value in stream: if token in ignored_tokens: continue elif token == TOKEN_LINESTATEMENT_BEGIN: token = TOKEN_BLOCK_BEGIN elif token == TOKEN_LINESTATEMENT_END: token = TOKEN_BLOCK_END # we are not interested in those tokens in the parser elif token in (TOKEN_RAW_BEGIN, TOKEN_RAW_END): continue elif token == TOKEN_DATA: value = self._normalize_newlines(value) elif token == 'keyword': token = value elif token == TOKEN_NAME: value = str(value) if check_ident and not value.isidentifier(): raise TemplateSyntaxError( 'Invalid character in identifier', lineno, name, filename) elif token == TOKEN_STRING: # try to unescape string try: value = self._normalize_newlines(value[1:-1]) \ .encode('ascii', 'backslashreplace') \ .decode('unicode-escape') except Exception as e: msg = str(e).split(':')[-1].strip() raise TemplateSyntaxError(msg, lineno, name, filename) elif token == TOKEN_INTEGER: value = int(value.replace("_", "")) elif token == TOKEN_FLOAT: # remove all "_" first to support more Python versions value = literal_eval(value.replace("_", "")) elif token == TOKEN_OPERATOR: token = operators[value] yield Token(lineno, token, value)
def wrap(self, stream, name=None, filename=None): """This is called with the stream as returned by `tokenize` and wraps every token in a :class:`Token` and converts the value. """ for lineno, token, value in stream: if token in ignored_tokens: continue elif token == 'linestatement_begin': token = 'block_begin' elif token == 'linestatement_end': token = 'block_end' # we are not interested in those tokens in the parser elif token in ('raw_begin', 'raw_end'): continue elif token == 'data': value = self._normalize_newlines(value) elif token == 'keyword': token = value elif token == 'name': value = str(value) if check_ident and not value.isidentifier(): raise TemplateSyntaxError( 'Invalid character in identifier', lineno, name, filename) elif token == 'string': # try to unescape string try: value = self._normalize_newlines(value[1:-1]) \ .encode('ascii', 'backslashreplace') \ .decode('unicode-escape') except Exception as e: msg = str(e).split(':')[-1].strip() raise TemplateSyntaxError(msg, lineno, name, filename) elif token == 'integer': value = int(value.replace("_", "")) elif token == 'float': # remove all "_" first to support more Python versions value = literal_eval(value.replace("_", "")) elif token == 'operator': token = operators[value] yield Token(lineno, token, value)
def parse(self, parser): stream = parser.stream tag = next(stream) if stream.current.test('string'): path = parser.parse_primary() else: raise TemplateSyntaxError(''' "%s" requires path to asset file''' % tag.value, tag.lineno) while not parser.stream.current.type == 'block_end': next(parser.stream) result = self.call_method('_build_url', args=[path]) return nodes.Output([nodes.MarkSafe(result)]).set_lineno(tag.lineno)
def filter_stream(self, stream): paren_stack = 0 for token in stream: if token.type != "data": yield token continue pos = 0 lineno = token.lineno while 1: if not paren_stack: match = _outside_re.search(token.value, pos) else: match = _inside_re.search(token.value, pos) if match is None: break new_pos = match.start() if new_pos > pos: preval = token.value[pos:new_pos] yield Token(lineno, "data", preval) lineno += count_newlines(preval) gtok = match.group() if gtok[0] == "\\": yield Token(lineno, "data", gtok[1:]) elif not paren_stack: yield Token(lineno, "block_begin", None) yield Token(lineno, "name", "trans") yield Token(lineno, "block_end", None) paren_stack = 1 else: if gtok == "(" or paren_stack > 1: yield Token(lineno, "data", gtok) paren_stack += gtok == ")" and -1 or 1 if not paren_stack: yield Token(lineno, "block_begin", None) yield Token(lineno, "name", "endtrans") yield Token(lineno, "block_end", None) pos = match.end() if pos < len(token.value): yield Token(lineno, "data", token.value[pos:]) if paren_stack: raise TemplateSyntaxError( "unclosed gettext expression", token.lineno, stream.name, stream.filename, )
def get_document_render_styles(doc_path) -> RenderStylesCollection: styles = RenderStylesCollection() doc: DocType = Document(doc_path) style_name = None attrs = dict() for element in _iter_block_items(doc): if not style_name and not isinstance(element, Paragraph): continue if not style_name: match = _BEGIN_STYLE.match(element.text) if match: style_name = match.group(1) else: if isinstance(element, Table): attrs['table'] = element._tblPr.xml else: text = element.text if _END_STYLE.match(text): styles.add_style(RenderStyle(name=style_name, **attrs)) style_name = None attrs = dict() continue match = _TAG_STYLE.match(text) if match: tag_name = match.group(1).lower() if tag_name in PARAGRAPH_STYLE_TAGS: # Get style from paragraph if element._element.pPr is not None: attrs[tag_name] = element._element.pPr.xml else: attrs[tag_name] = '<w:pPr></w:pPr>' elif tag_name in RAW_STYLE_TAGS: # Get style from Run if element.runs[0]._element.rPr is not None: attrs[tag_name] = element.runs[0]._element.rPr.xml else: attrs[tag_name] = '<w:rPr></w:rPr>' if style_name is not None: raise TemplateSyntaxError( 'Unexpected end of template style definition {}. Never closed'.format(style_name), None ) return styles
def parse(self, parser): lineno = parser.stream.next().lineno token = next(parser.stream) if token.value not in self.allowed_languages: raise TemplateSyntaxError( 'Expected language token from set: %s' % ', '.join(self.allowed_languages), lineno) body = parser.parse_statements(['name:endshow'], drop_needle=True) node = nodes.CallBlock( self.call_method('_show_support', [nodes.Const(token.value)]), [], [], body).set_lineno(lineno) return node
def thumbnail_obj(source, size, **opts): """Make thumbnail from source image""" if not source: return None raise_errors = thumbnailer_settings.THUMBNAIL_DEBUG accepted_opts = {} for key, value in opts.items(): if key in VALID_OPTIONS: accepted_opts[key] = value opts = accepted_opts m = RE_SIZE.match(size) if m: opts['size'] = (int(m.group(1)), int(m.group(2))) else: if raise_errors: raise TemplateSyntaxError('%r is not a valid size.' % size, 1) if 'quality' in opts: try: opts['quality'] = int(opts['quality']) except (TypeError, ValueError): if raise_errors: raise TemplateSyntaxError( '%r is an invalid quality.' % opts['quality'], 1) try: curr_thumbnail = get_thumbnailer(source).get_thumbnail(opts) except Exception as e: if raise_errors: raise TemplateSyntaxError( 'Couldn\'t get the thumbnail %s: %s' % (source, e), 1) else: return None return curr_thumbnail
def parse(self, parser): stream = parser.stream tag = stream.next() if stream.current.test('string'): path = parser.parse_primary() else: raise TemplateSyntaxError( '''\ "%s" requires path to asset file, relative to STATICFILES_URL''' % tag.value, tag.lineno) while not parser.stream.current.type == 'block_end': parser.stream.next() result = self.call_method(self.build_method, args=[path]) return nodes.Output([nodes.MarkSafe(result)]).set_lineno(tag.lineno)
def addfilter(env: "Environment", token: "Token", parser: "Parser") -> nodes.Node: """The addfilter tag {% addfilter name ... %} ... {% endaddfilter %} This allows one to use the python code inside the body to add a filter or replace an existing filter Args: env: The environment token: The token matches tag name parser: The parser Returns: The parsed node """ token = parser.stream.expect("name") filtername = token.value pass_env: Union[bool, Token] if parser.stream.current.type is TOKEN_BLOCK_END: # no pass_environment pass_env = False else: pass_env = parser.stream.expect("name:pass_env") body = parser.parse_statements(("name:endaddfilter", ), drop_needle=True) body = decode_raw(body[0].nodes[0].data) body_parts = body.split("\n", 1) if not body_parts[0]: body = "" if len(body_parts) < 2 else body_parts[1] body = textwrap.dedent(body) globs = env.globals.copy() code = compile(body, "<liquid-addfilter-tag>", mode="exec") exec(code, globs) try: filterfunc = globs[filtername] except KeyError: raise TemplateSyntaxError( f"No such filter defined in 'addfilter': {filtername}", token.lineno, ) from None if pass_env: filterfunc = pass_environment(filterfunc) # type: ignore env.filters[filtername] = filterfunc return nodes.Output([], lineno=token.lineno)
def __getitem__(self, key): if not isinstance(key, string_types): raise ValueError('key must be a string') key = to_native(key) if '.' not in key: # might be a built-in value, delegate to base dict return self._delegatee.__getitem__(key) func = self._collection_jinja_func_cache.get(key) if func: return func acr = AnsibleCollectionRef.try_parse_fqcr(key, self._dirname) if not acr: raise KeyError('invalid plugin name: {0}'.format(key)) try: pkg = import_module(acr.n_python_package_name) except ImportError: raise KeyError() parent_prefix = acr.collection if acr.subdirs: parent_prefix = '{0}.{1}'.format(parent_prefix, acr.subdirs) for dummy, module_name, ispkg in pkgutil.iter_modules( pkg.__path__, prefix=parent_prefix + '.'): if ispkg: continue try: plugin_impl = self._pluginloader.get(module_name) except Exception as e: raise TemplateSyntaxError(to_native(e), 0) method_map = getattr(plugin_impl, self._method_map_name) for f in iteritems(method_map()): fq_name = '.'.join((parent_prefix, f[0])) # FIXME: detect/warn on intra-collection function name collisions self._collection_jinja_func_cache[fq_name] = f[1] function_impl = self._collection_jinja_func_cache[key] return function_impl
def filter_stream(self, stream): paren_stack = 0 for token in stream: if token.type is not 'data': yield token continue pos = 0 lineno = token.lineno while 1: if not paren_stack: match = _outside_re.search(token.value, pos) else: match = _inside_re.search(token.value, pos) if match is None: break new_pos = match.start() if new_pos > pos: preval = token.value[pos:new_pos] yield Token(lineno, 'data', preval) lineno += count_newlines(preval) gtok = match.group() if gtok[0] == '\\': yield Token(lineno, 'data', gtok[1:]) elif not paren_stack: yield Token(lineno, 'block_begin', None) yield Token(lineno, 'name', 'trans') yield Token(lineno, 'block_end', None) paren_stack = 1 else: if gtok == '(' or paren_stack > 1: yield Token(lineno, 'data', gtok) paren_stack += gtok == ')' and -1 or 1 if not paren_stack: yield Token(lineno, 'block_begin', None) yield Token(lineno, 'name', 'endtrans') yield Token(lineno, 'block_end', None) pos = match.end() if pos < len(token.value): yield Token(lineno, 'data', token.value[pos:]) if paren_stack: raise TemplateSyntaxError('unclosed gettext expression', token.lineno, stream.name, stream.filename)
def compile_expression(self, source, undefined_to_none=True): """A handy helper method that returns a callable that accepts keyword arguments that appear as variables in the expression. If called it returns the result of the expression. This is useful if applications want to use the same rules as Jinja in template "configuration files" or similar situations. Example usage: >>> env = Environment() >>> expr = env.compile_expression('foo == 42') >>> expr(foo=23) False >>> expr(foo=42) True Per default the return value is converted to `None` if the expression returns an undefined value. This can be changed by setting `undefined_to_none` to `False`. >>> env.compile_expression('var')() is None True >>> env.compile_expression('var', undefined_to_none=False)() Undefined .. versionadded:: 2.1 """ parser = Parser(self, source, state='variable') exc_info = None try: expr = parser.parse_expression() if not parser.stream.eos: raise TemplateSyntaxError('chunk after expression', parser.stream.current.lineno, None, None) expr.set_environment(self) except TemplateSyntaxError: exc_info = sys.exc_info() if exc_info is not None: self.handle_exception(exc_info, source_hint=source) body = [nodes.Assign(nodes.Name('result', 'store'), expr, lineno=1)] template = self.from_string(nodes.Template(body, lineno=1)) return TemplateExpression(template, undefined_to_none)
def wrap(self, stream, name=None, filename=None): """This is called with the stream as returned by `tokenize` and wraps every token in a :class:`Token` and converts the value. """ for lineno, token, value in stream: if token in ignored_tokens: continue elif token == 'linestatement_begin': token = 'block_begin' elif token == 'linestatement_end': token = 'block_end' # we are not interested in those tokens in the parser elif token in ('raw_begin', 'raw_end'): continue elif token == 'data': value = self._normalize_newlines(value) elif token == 'keyword': token = value elif token == 'name': value = str(value) elif token == 'string': # try to unescape string try: value = self._normalize_newlines(value[1:-1]) \ .encode('ascii', 'backslashreplace') \ .decode('unicode-escape') except Exception as e: msg = str(e).split(':')[-1].strip() raise TemplateSyntaxError(msg, lineno, name, filename) # if we can express it as bytestring (ascii only) # we do that for support of semi broken APIs # as datetime.datetime.strftime. On python 3 this # call becomes a noop thanks to 2to3 if PY2: try: value = value.encode('ascii') except UnicodeError: pass elif token == 'integer': value = int(value) elif token == 'float': value = float(value) elif token == 'operator': token = operators[value] yield Token(lineno, token, value)
def compile_expression(self, source, undefined_to_none=True): parser = Parser(self, source, state='variable') exc_info = None try: expr = parser.parse_expression() if not parser.stream.eos: raise TemplateSyntaxError('chunk after expression', parser.stream.current.lineno, None, None) expr.set_environment(self) except TemplateSyntaxError: exc_info = sys.exc_info() if exc_info is not None: self.handle_exception(exc_info, source_hint=source) body = [nodes.Assign(nodes.Name('result', 'store'), expr, lineno=1)] template = self.from_string(nodes.Template(body, lineno=1)) return TemplateExpression(template, undefined_to_none)
def _cache_support(self, expire_time, fragm_name, vary_on, lineno, caller): from django.core.cache import cache # delay depending in settings from django.utils.http import urlquote try: expire_time = int(expire_time) except (ValueError, TypeError): raise TemplateSyntaxError( '"%s" tag got a non-integer ' 'timeout value: %r' % (list(self.tags)[0], expire_time), lineno) cache_key = u':'.join([fragm_name] + [urlquote(v) for v in vary_on]) value = cache.get(cache_key) if value is None: value = caller() cache.set(cache_key, value, expire_time) return value
def _cache_support(self, expire_time, fragm_name, vary_on, lineno, caller): from hashlib import md5 from django.core.cache import cache # delay depending in settings from django.utils.http import urlquote try: expire_time = int(expire_time) except (ValueError, TypeError): raise TemplateSyntaxError('"%s" tag got a non-integer timeout ' 'value: %r' % (list(self.tags)[0], expire_time), lineno) args_string = u':'.join([urlquote(v) for v in vary_on]) args_md5 = md5(args_string) cache_key = 'template.cache.%s.%s' % (fragm_name, args_md5.hexdigest()) value = cache.get(cache_key) if value is None: value = caller() cache.set(cache_key, value, expire_time) return value