root/galaxy-central/eggs/Mako-0.2.5-py2.6.egg/mako/ast.py

リビジョン 3, 5.1 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# ast.py
2# Copyright (C) 2006, 2007, 2008, 2009 Michael Bayer mike_mp@zzzcomputing.com
3#
4# This module is part of Mako and is released under
5# the MIT License: http://www.opensource.org/licenses/mit-license.php
6
7"""utilities for analyzing expressions and blocks of Python code, as well as generating Python from AST nodes"""
8
9from mako import exceptions, pyparser, util
10import re
11
12class PythonCode(object):
13    """represents information about a string containing Python code"""
14    def __init__(self, code, **exception_kwargs):
15        self.code = code
16       
17        # represents all identifiers which are assigned to at some point in the code
18        self.declared_identifiers = util.Set()
19       
20        # represents all identifiers which are referenced before their assignment, if any
21        self.undeclared_identifiers = util.Set()
22       
23        # note that an identifier can be in both the undeclared and declared lists.
24
25        # using AST to parse instead of using code.co_varnames, code.co_names has several advantages:
26        # - we can locate an identifier as "undeclared" even if its declared later in the same block of code
27        # - AST is less likely to break with version changes (for example, the behavior of co_names changed a little bit
28        # in python version 2.5)
29        if isinstance(code, basestring):
30            expr = pyparser.parse(code.lstrip(), "exec", **exception_kwargs)
31        else:
32            expr = code
33
34        f = pyparser.FindIdentifiers(self, **exception_kwargs)
35        f.visit(expr)
36
37class ArgumentList(object):
38    """parses a fragment of code as a comma-separated list of expressions"""
39    def __init__(self, code, **exception_kwargs):
40        self.codeargs = []
41        self.args = []
42        self.declared_identifiers = util.Set()
43        self.undeclared_identifiers = util.Set()
44        if isinstance(code, basestring):
45            if re.match(r"\S", code) and not re.match(r",\s*$", code):
46                # if theres text and no trailing comma, insure its parsed
47                # as a tuple by adding a trailing comma
48                code  += ","
49            expr = pyparser.parse(code, "exec", **exception_kwargs)
50        else:
51            expr = code
52
53        f = pyparser.FindTuple(self, PythonCode, **exception_kwargs)
54        f.visit(expr)
55       
56class PythonFragment(PythonCode):
57    """extends PythonCode to provide identifier lookups in partial control statements
58   
59    e.g.
60        for x in 5:
61        elif y==9:
62        except (MyException, e):
63    etc.
64    """
65    def __init__(self, code, **exception_kwargs):
66        m = re.match(r'^(\w+)(?:\s+(.*?))?:\s*(#|$)', code.strip(), re.S)
67        if not m:
68            raise exceptions.CompileException("Fragment '%s' is not a partial control statement" % code, **exception_kwargs)
69        if m.group(3):
70            code = code[:m.start(3)]
71        (keyword, expr) = m.group(1,2)
72        if keyword in ['for','if', 'while']:
73            code = code + "pass"
74        elif keyword == 'try':
75            code = code + "pass\nexcept:pass"
76        elif keyword == 'elif' or keyword == 'else':
77            code = "if False:pass\n" + code + "pass"
78        elif keyword == 'except':
79            code = "try:pass\n" + code + "pass"
80        else:
81            raise exceptions.CompileException("Unsupported control keyword: '%s'" % keyword, **exception_kwargs)
82        super(PythonFragment, self).__init__(code, **exception_kwargs)
83       
84       
85class FunctionDecl(object):
86    """function declaration"""
87    def __init__(self, code, allow_kwargs=True, **exception_kwargs):
88        self.code = code
89        expr = pyparser.parse(code, "exec", **exception_kwargs)
90               
91        f = pyparser.ParseFunc(self, **exception_kwargs)
92        f.visit(expr)
93        if not hasattr(self, 'funcname'):
94            raise exceptions.CompileException("Code '%s' is not a function declaration" % code, **exception_kwargs)
95        if not allow_kwargs and self.kwargs:
96            raise exceptions.CompileException("'**%s' keyword argument not allowed here" % self.argnames[-1], **exception_kwargs)
97           
98    def get_argument_expressions(self, include_defaults=True):
99        """return the argument declarations of this FunctionDecl as a printable list."""
100        namedecls = []
101        defaults = [d for d in self.defaults]
102        kwargs = self.kwargs
103        varargs = self.varargs
104        argnames = [f for f in self.argnames]
105        argnames.reverse()
106        for arg in argnames:
107            default = None
108            if kwargs:
109                arg = "**" + arg
110                kwargs = False
111            elif varargs:
112                arg = "*" + arg
113                varargs = False
114            else:
115                default = len(defaults) and defaults.pop() or None
116            if include_defaults and default:
117                namedecls.insert(0, "%s=%s" % (arg, pyparser.ExpressionGenerator(default).value()))
118            else:
119                namedecls.insert(0, arg)
120        return namedecls
121
122class FunctionArgs(FunctionDecl):
123    """the argument portion of a function declaration"""
124    def __init__(self, code, **kwargs):
125        super(FunctionArgs, self).__init__("def ANON(%s):pass" % code, **kwargs)
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。