Ejemplo n.º 1
0
    def __init__(self, keyword, attributes, **kwargs):
        expressions = ['buffered', 'cached', 'args'] + [
            c for c in attributes if c.startswith('cache_')]

        super(BlockTag, self).__init__(
            keyword,
            attributes,
            expressions,
            ('name', 'filter', 'decorator'),
            (),
            **kwargs)
        name = attributes.get('name')
        if name and not re.match(r'^[\w_]+$', name):
            raise exceptions.CompileException(
                "%block may not specify an argument signature",
                **self.exception_kwargs)
        if not name and attributes.get('args', None):
            raise exceptions.CompileException(
                "Only named %blocks may specify args",
                **self.exception_kwargs
            )
        self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
                                          **self.exception_kwargs)

        self.name = name
        self.decorator = attributes.get('decorator', '')
        self.filter_args = ast.ArgumentList(
            attributes.get('filter', ''),
            **self.exception_kwargs)
Ejemplo n.º 2
0
 def __init__(self, code, **exception_kwargs):
     m = re.match(r'^(\w+)(?:\s+(.*?))?:\s*(#|$)', code.strip(), re.S)
     if not m:
         raise exceptions.CompileException(
             "Fragment '%s' is not a partial control statement" % code,
             **exception_kwargs)
     if m.group(3):
         code = code[:m.start(3)]
     (keyword, expr) = m.group(1, 2)
     if keyword == 'for':
         thevar = re.sub(r'^for (.+?) in .*', r'\1', code)
         if thevar and thevar != code:
             self.names_set = set([thevar])
     if keyword in ['for', 'if', 'while']:
         code = code + "pass"
     elif keyword == 'try':
         code = code + "pass\nexcept:pass"
     elif keyword == 'elif' or keyword == 'else':
         code = "if False:pass\n" + code + "pass"
     elif keyword == 'except':
         thevar = re.sub(r'^.*(,| as)\s+([a-zA-z\_][0-9a-zA-Z\_]*):.*',
                         r'\2', code)
         if thevar and thevar != code:
             self.names_set = set([thevar])
         code = "try:pass\n" + code + "pass"
     elif keyword == 'with':
         code = code + "pass"
     else:
         raise exceptions.CompileException(
             "Unsupported control keyword: '%s'" % keyword,
             **exception_kwargs)
     super(PythonFragment, self).__init__(code, **exception_kwargs)
Ejemplo n.º 3
0
    def visitBlockTag(self, node):
        if node is not self.node and not node.is_anonymous:

            if isinstance(self.node, parsetree.DefTag):
                raise exceptions.CompileException(
                    "Named block '%s' not allowed inside of def '%s'" %
                    (node.name, self.node.name), **node.exception_kwargs)
            elif isinstance(self.node,
                            (parsetree.CallTag, parsetree.CallNamespaceTag)):
                raise exceptions.CompileException(
                    "Named block '%s' not allowed inside of <%%call> tag" %
                    (node.name, ), **node.exception_kwargs)

        for ident in node.undeclared_identifiers():
            if ident != 'context' and \
                    ident not in self.declared.union(self.locally_declared):
                self.undeclared.add(ident)

        if not node.is_anonymous:
            self._check_name_exists(self.topleveldefs, node)
            self.undeclared.add(node.funcname)
        elif node is not self.node:
            self._check_name_exists(self.closuredefs, node)
        for ident in node.declared_identifiers():
            self.argument_declared.add(ident)
        for n in node.nodes:
            n.accept_visitor(self)
Ejemplo n.º 4
0
    def __init__(self, code, allow_kwargs=True, **exception_kwargs):
        self.code = code
        expr = pyparser.parse(code, "exec", **exception_kwargs)

        f = pyparser.ParseFunc(self, **exception_kwargs)
        f.visit(expr)
        if not hasattr(self, 'funcname'):
            raise exceptions.CompileException(
                "Code '%s' is not a function declaration" % code,
                **exception_kwargs)
        if not allow_kwargs and self.kwargs:
            raise exceptions.CompileException(
                "'**%s' keyword argument not allowed here" %
                self.kwargnames[-1], **exception_kwargs)
Ejemplo n.º 5
0
    def __init__(self, keyword, attributes, **kwargs):
        super(NamespaceTag,
              self).__init__(keyword, attributes, ('file', ),
                             ('name', 'inheritable', 'import', 'module'), (),
                             **kwargs)

        self.name = attributes.get('name', '__anon_%s' % hex(abs(id(self))))
        if 'name' not in attributes and 'import' not in attributes:
            raise exceptions.CompileException(
                "'name' and/or 'import' attributes are required "
                "for <%namespace>", **self.exception_kwargs)
        if 'file' in attributes and 'module' in attributes:
            raise exceptions.CompileException(
                "<%namespace> may only have one of 'file' or 'module'",
                **self.exception_kwargs)
Ejemplo n.º 6
0
 def visitDefOrBase(s, node):
     if node.is_anonymous:
         raise exceptions.CompileException(
             "Can't put anonymous blocks inside "
             "<%namespace>", **node.exception_kwargs)
     self.write_inline_def(node, identifiers, nested=False)
     export.append(node.funcname)
Ejemplo n.º 7
0
    def __init__(self, keyword, attributes, expressions, nonexpressions,
                 required, **kwargs):
        """construct a new Tag instance.

        this constructor not called directly, and is only called
        by subclasses.

        :param keyword: the tag keyword

        :param attributes: raw dictionary of attribute key/value pairs

        :param expressions: a set of identifiers that are legal attributes,
         which can also contain embedded expressions

        :param nonexpressions: a set of identifiers that are legal
         attributes, which cannot contain embedded expressions

        :param \**kwargs:
         other arguments passed to the Node superclass (lineno, pos)

        """
        super(Tag, self).__init__(**kwargs)
        self.keyword = keyword
        self.attributes = attributes
        self._parse_attributes(expressions, nonexpressions)
        missing = [r for r in required if r not in self.parsed_attributes]
        if len(missing):
            raise exceptions.CompileException(
                "Missing attribute(s): %s" %
                ",".join([repr(m) for m in missing]), **self.exception_kwargs)
        self.parent = None
        self.nodes = []
Ejemplo n.º 8
0
 def _check_name_exists(self, collection, node):
     existing = collection.get(node.funcname)
     collection[node.funcname] = node
     if existing is not None and \
             existing is not node and \
             (node.is_block or existing.is_block):
         raise exceptions.CompileException(
             "%%def or %%block named '%s' already "
             "exists in this template." % node.funcname,
             **node.exception_kwargs)
Ejemplo n.º 9
0
 def visit_ImportFrom(self, node):
     for name in node.names:
         if name.asname is not None:
             self._add_declared(name.asname)
         else:
             if name.name == '*':
                 raise exceptions.CompileException(
                     "'import *' is not supported, since all identifier "
                     "names must be explicitly declared.  Please use the "
                     "form 'from <modulename> import <name1>, <name2>, "
                     "...' instead.", **self.exception_kwargs)
             self._add_declared(name.name)
Ejemplo n.º 10
0
    def parse(self):
        self.encoding, self.text = self.decode_raw_stream(
            self.text,
            not self.disable_unicode,
            self.encoding,
            self.filename)

        for preproc in self.preprocessor:
            self.text = preproc(self.text)

        # push the match marker past the
        # encoding comment.
        self.match_reg(self._coding_re)

        self.textlength = len(self.text)

        while (True):
            if self.match_position > self.textlength:
                break

            if self.match_end():
                break
            if self.match_expression():
                continue
            if self.match_control_line():
                continue
            if self.match_comment():
                continue
            if self.match_tag_start():
                continue
            if self.match_tag_end():
                continue
            if self.match_python_block():
                continue
            if self.match_text():
                continue

            if self.match_position > self.textlength:
                break
            raise exceptions.CompileException("assertion failed")

        if len(self.tag):
            raise exceptions.SyntaxException("Unclosed tag: <%%%s>" %
                                             self.tag[-1].keyword,
                                             **self.exception_kwargs)
        if len(self.control_line):
            raise exceptions.SyntaxException(
                "Unterminated control keyword: '%s'" %
                self.control_line[-1].keyword,
                self.text,
                self.control_line[-1].lineno,
                self.control_line[-1].pos, self.filename)
        return self.template
Ejemplo n.º 11
0
    def decode_raw_stream(self, text, decode_raw, known_encoding, filename):
        """given string/unicode or bytes/string, determine encoding
           from magic encoding comment, return body as unicode
           or raw if decode_raw=False

        """
        if isinstance(text, compat.text_type):
            m = self._coding_re.match(text)
            encoding = m and m.group(1) or known_encoding or 'ascii'
            return encoding, text

        if text.startswith(codecs.BOM_UTF8):
            text = text[len(codecs.BOM_UTF8):]
            parsed_encoding = 'utf-8'
            m = self._coding_re.match(text.decode('utf-8', 'ignore'))
            if m is not None and m.group(1) != 'utf-8':
                raise exceptions.CompileException(
                    "Found utf-8 BOM in file, with conflicting "
                    "magic encoding comment of '%s'" % m.group(1),
                    text.decode('utf-8', 'ignore'),
                    0, 0, filename)
        else:
            m = self._coding_re.match(text.decode('utf-8', 'ignore'))
            if m:
                parsed_encoding = m.group(1)
            else:
                parsed_encoding = known_encoding or 'ascii'

        if decode_raw:
            try:
                text = text.decode(parsed_encoding)
            except UnicodeDecodeError:
                raise exceptions.CompileException(
                    "Unicode decode operation of encoding '%s' failed" %
                    parsed_encoding,
                    text.decode('utf-8', 'ignore'),
                    0, 0, filename)

        return parsed_encoding, text
Ejemplo n.º 12
0
 def _parse_attributes(self, expressions, nonexpressions):
     undeclared_identifiers = set()
     self.parsed_attributes = {}
     for key in self.attributes:
         if key in expressions:
             expr = []
             for x in re.compile(r'(\${.+?})',
                                 re.S).split(self.attributes[key]):
                 m = re.compile(r'^\${(.+?)}$', re.S).match(x)
                 if m:
                     code = ast.PythonCode(m.group(1).rstrip(),
                                           **self.exception_kwargs)
                     # we aren't discarding "declared_identifiers" here,
                     # which we do so that list comprehension-declared
                     # variables aren't counted.   As yet can't find a
                     # condition that requires it here.
                     undeclared_identifiers = \
                         undeclared_identifiers.union(
                             code.undeclared_identifiers)
                     expr.append('(%s)' % m.group(1))
                 else:
                     if x:
                         expr.append(repr(x))
             self.parsed_attributes[key] = " + ".join(expr) or repr('')
         elif key in nonexpressions:
             if re.search(r'\${.+?}', self.attributes[key]):
                 raise exceptions.CompileException(
                     "Attibute '%s' in tag '%s' does not allow embedded "
                     "expressions" % (key, self.keyword),
                     **self.exception_kwargs)
             self.parsed_attributes[key] = repr(self.attributes[key])
         else:
             raise exceptions.CompileException(
                 "Invalid attribute for tag '%s': '%s'" %
                 (self.keyword, key),
                 **self.exception_kwargs)
     self.expression_undeclared_identifiers = undeclared_identifiers
Ejemplo n.º 13
0
 def __init__(self, code, **exception_kwargs):
     m = re.match(r'^(\w+)(?:\s+(.*?))?:\s*(#|$)', code.strip(), re.S)
     if not m:
         raise exceptions.CompileException(
             "Fragment '%s' is not a partial control statement" % code,
             **exception_kwargs)
     if m.group(3):
         code = code[:m.start(3)]
     (keyword, expr) = m.group(1, 2)
     if keyword in ['for', 'if', 'while']:
         code = code + "pass"
     elif keyword == 'try':
         code = code + "pass\nexcept:pass"
     elif keyword == 'elif' or keyword == 'else':
         code = "if False:pass\n" + code + "pass"
     elif keyword == 'except':
         code = "try:pass\n" + code + "pass"
     elif keyword == 'with':
         code = code + "pass"
     else:
         raise exceptions.CompileException(
             "Unsupported control keyword: '%s'" % keyword,
             **exception_kwargs)
     super(PythonFragment, self).__init__(code, **exception_kwargs)
Ejemplo n.º 14
0
    def __call__(cls, keyword, attributes, **kwargs):
        if ":" in keyword:
            ns, defname = keyword.split(':')
            return type.__call__(CallNamespaceTag, ns, defname, attributes,
                                 **kwargs)

        try:
            cls = _TagMeta._classmap[keyword]
        except KeyError:
            raise exceptions.CompileException("No such tag: '%s'" % keyword,
                                              source=kwargs['source'],
                                              lineno=kwargs['lineno'],
                                              pos=kwargs['pos'],
                                              filename=kwargs['filename'])
        return type.__call__(cls, keyword, attributes, **kwargs)
Ejemplo n.º 15
0
    def __init__(self, keyword, attributes, **kwargs):
        expressions = ['buffered', 'cached'
                       ] + [c for c in attributes if c.startswith('cache_')]

        super(DefTag, self).__init__(keyword, attributes, expressions,
                                     ('name', 'filter', 'decorator'),
                                     ('name', ), **kwargs)
        name = attributes['name']
        if re.match(r'^[\w_]+$', name):
            raise exceptions.CompileException("Missing parenthesis in %def",
                                              **self.exception_kwargs)
        self.function_decl = ast.FunctionDecl("def " + name + ":pass",
                                              **self.exception_kwargs)
        self.name = self.function_decl.funcname
        self.decorator = attributes.get('decorator', '')
        self.filter_args = ast.ArgumentList(attributes.get('filter', ''),
                                            **self.exception_kwargs)