aboutsummaryrefslogtreecommitdiffstats
path: root/mako/pyparser.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-11-13 14:16:10 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2010-11-13 14:16:10 -0500
commit4905370b965f7ccaf866c2cfbf9266e265d66709 (patch)
tree07dbb65ffa17681b67f8706629694075971653d5 /mako/pyparser.py
parent6eea95175349e1e2383e74a1157ffbdee5a258d4 (diff)
downloadexternal_python_mako-4905370b965f7ccaf866c2cfbf9266e265d66709.tar.gz
external_python_mako-4905370b965f7ccaf866c2cfbf9266e265d66709.tar.bz2
external_python_mako-4905370b965f7ccaf866c2cfbf9266e265d66709.zip
- [ticket:98] for the pyparser module
Diffstat (limited to 'mako/pyparser.py')
-rw-r--r--mako/pyparser.py297
1 files changed, 201 insertions, 96 deletions
diff --git a/mako/pyparser.py b/mako/pyparser.py
index d011690..ab9c2b6 100644
--- a/mako/pyparser.py
+++ b/mako/pyparser.py
@@ -52,35 +52,49 @@ def parse(code, mode='exec', **exception_kwargs):
code = code.encode('ascii', 'backslashreplace')
return compiler_parse(code, mode)
except Exception, e:
- raise exceptions.SyntaxException("(%s) %s (%s)" % (e.__class__.__name__, str(e), repr(code[0:50])), **exception_kwargs)
+ raise exceptions.SyntaxException(
+ "(%s) %s (%r)" % (
+ e.__class__.__name__,
+ e,
+ code[0:50]
+ ), **exception_kwargs)
if _ast:
class FindIdentifiers(_ast_util.NodeVisitor):
+
def __init__(self, listener, **exception_kwargs):
self.in_function = False
self.in_assign_targets = False
self.local_ident_stack = {}
self.listener = listener
self.exception_kwargs = exception_kwargs
+
def _add_declared(self, name):
if not self.in_function:
self.listener.declared_identifiers.add(name)
+
def visit_ClassDef(self, node):
self._add_declared(node.name)
+
def visit_Assign(self, node):
- # flip around the visiting of Assign so the expression gets evaluated first,
- # in the case of a clause like "x=x+5" (x is undeclared)
+
+ # flip around the visiting of Assign so the expression gets
+ # evaluated first, in the case of a clause like "x=x+5" (x
+ # is undeclared)
+
self.visit(node.value)
in_a = self.in_assign_targets
self.in_assign_targets = True
for n in node.targets:
self.visit(n)
self.in_assign_targets = in_a
-
+
if util.py3k:
- # ExceptHandler is in Python 2, but this
- # block only works in Python 3 (and is required there)
+
+ # ExceptHandler is in Python 2, but this block only works in
+ # Python 3 (and is required there)
+
def visit_ExceptHandler(self, node):
if node.name is not None:
self._add_declared(node.name)
@@ -88,24 +102,25 @@ if _ast:
self.listener.undeclared_identifiers.add(node.type.id)
for statement in node.body:
self.visit(statement)
-
+
def visit_Lambda(self, node, *args):
self._visit_function(node, True)
def visit_FunctionDef(self, node):
self._add_declared(node.name)
self._visit_function(node, False)
-
+
def _visit_function(self, node, islambda):
- # push function state onto stack. dont log any
- # more identifiers as "declared" until outside of the function,
- # but keep logging identifiers as "undeclared".
- # track argument names in each function header
- # so they arent counted as "undeclared"
+
+ # push function state onto stack. dont log any more
+ # identifiers as "declared" until outside of the function,
+ # but keep logging identifiers as "undeclared". track
+ # argument names in each function header so they arent
+ # counted as "undeclared"
+
saved = {}
inf = self.in_function
self.in_function = True
-
for arg in node.args.args:
if arg_id(arg) in self.local_ident_stack:
saved[arg_id(arg)] = True
@@ -120,28 +135,33 @@ if _ast:
for arg in node.args.args:
if arg_id(arg) not in saved:
del self.local_ident_stack[arg_id(arg)]
-
+
def visit_For(self, node):
+
# flip around visit
+
self.visit(node.iter)
self.visit(node.target)
for statement in node.body:
self.visit(statement)
for statement in node.orelse:
self.visit(statement)
+
def visit_Name(self, node):
if isinstance(node.ctx, _ast.Store):
self._add_declared(node.id)
- if node.id not in reserved and \
- node.id not in self.listener.declared_identifiers and \
- node.id not in self.local_ident_stack:
+ if node.id not in reserved and node.id \
+ not in self.listener.declared_identifiers and node.id \
+ not in self.local_ident_stack:
self.listener.undeclared_identifiers.add(node.id)
+
def visit_Import(self, node):
for name in node.names:
if name.asname is not None:
self._add_declared(name.asname)
else:
self._add_declared(name.name.split('.')[0])
+
def visit_ImportFrom(self, node):
for name in node.names:
if name.asname is not None:
@@ -149,32 +169,39 @@ if _ast:
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)
+ "'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)
+
class FindTuple(_ast_util.NodeVisitor):
+
def __init__(self, listener, code_factory, **exception_kwargs):
self.listener = listener
self.exception_kwargs = exception_kwargs
self.code_factory = code_factory
+
def visit_Tuple(self, node):
for n in node.elts:
p = self.code_factory(n, **self.exception_kwargs)
self.listener.codeargs.append(p)
self.listener.args.append(ExpressionGenerator(n).value())
- self.listener.declared_identifiers = self.listener.declared_identifiers.union(p.declared_identifiers)
- self.listener.undeclared_identifiers = self.listener.undeclared_identifiers.union(p.undeclared_identifiers)
+ self.listener.declared_identifiers = \
+ self.listener.declared_identifiers.union(
+ p.declared_identifiers)
+ self.listener.undeclared_identifiers = \
+ self.listener.undeclared_identifiers.union(
+ p.undeclared_identifiers)
+
class ParseFunc(_ast_util.NodeVisitor):
+
def __init__(self, listener, **exception_kwargs):
self.listener = listener
self.exception_kwargs = exception_kwargs
-
+
def visit_FunctionDef(self, node):
self.listener.funcname = node.name
argnames = [arg_id(arg) for arg in node.args.args]
@@ -183,47 +210,63 @@ if _ast:
if node.args.kwarg:
argnames.append(node.args.kwarg)
self.listener.argnames = argnames
- self.listener.defaults = node.args.defaults # ast
+ self.listener.defaults = node.args.defaults # ast
self.listener.varargs = node.args.vararg
self.listener.kwargs = node.args.kwarg
+
class ExpressionGenerator(object):
+
def __init__(self, astnode):
self.generator = _ast_util.SourceGenerator(' ' * 4)
self.generator.visit(astnode)
+
def value(self):
return ''.join(self.generator.result)
else:
class FindIdentifiers(object):
+
def __init__(self, listener, **exception_kwargs):
self.in_function = False
self.local_ident_stack = {}
self.listener = listener
self.exception_kwargs = exception_kwargs
+
def _add_declared(self, name):
if not self.in_function:
self.listener.declared_identifiers.add(name)
+
def visitClass(self, node, *args):
self._add_declared(node.name)
+
def visitAssName(self, node, *args):
self._add_declared(node.name)
+
def visitAssign(self, node, *args):
- # flip around the visiting of Assign so the expression gets evaluated first,
- # in the case of a clause like "x=x+5" (x is undeclared)
+
+ # flip around the visiting of Assign so the expression gets
+ # evaluated first, in the case of a clause like "x=x+5" (x
+ # is undeclared)
+
self.visit(node.expr, *args)
for n in node.nodes:
self.visit(n, *args)
+
def visitLambda(self, node, *args):
self._visit_function(node, args)
- def visitFunction(self,node, *args):
+
+ def visitFunction(self, node, *args):
self._add_declared(node.name)
self._visit_function(node, args)
+
def _visit_function(self, node, args):
- # push function state onto stack. dont log any
- # more identifiers as "declared" until outside of the function,
- # but keep logging identifiers as "undeclared".
- # track argument names in each function header so
- # they arent counted as "undeclared"
+
+ # push function state onto stack. dont log any more
+ # identifiers as "declared" until outside of the function,
+ # but keep logging identifiers as "undeclared". track
+ # argument names in each function header so they arent
+ # counted as "undeclared"
+
saved = {}
inf = self.in_function
self.in_function = True
@@ -238,191 +281,253 @@ else:
for arg in node.argnames:
if arg not in saved:
del self.local_ident_stack[arg]
-
+
def visitFor(self, node, *args):
+
# flip around visit
+
self.visit(node.list, *args)
self.visit(node.assign, *args)
self.visit(node.body, *args)
+
def visitName(self, node, *args):
- if node.name not in reserved and node.name not in self.listener.declared_identifiers and node.name not in self.local_ident_stack:
+ if node.name not in reserved and node.name \
+ not in self.listener.declared_identifiers and node.name \
+ not in self.local_ident_stack:
self.listener.undeclared_identifiers.add(node.name)
+
def visitImport(self, node, *args):
- for (mod, alias) in node.names:
+ for mod, alias in node.names:
if alias is not None:
self._add_declared(alias)
else:
self._add_declared(mod.split('.')[0])
+
def visitFrom(self, node, *args):
- for (mod, alias) in node.names:
+ for mod, alias in node.names:
if alias is not None:
self._add_declared(alias)
else:
if mod == '*':
- 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)
+ 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(mod)
+
def visit(self, expr):
- visitor.walk(expr, self) #, walker=walker())
+ visitor.walk(expr, self) # , walker=walker())
+
class FindTuple(object):
+
def __init__(self, listener, code_factory, **exception_kwargs):
self.listener = listener
self.exception_kwargs = exception_kwargs
self.code_factory = code_factory
+
def visitTuple(self, node, *args):
for n in node.nodes:
p = self.code_factory(n, **self.exception_kwargs)
self.listener.codeargs.append(p)
self.listener.args.append(ExpressionGenerator(n).value())
- self.listener.declared_identifiers = self.listener.declared_identifiers.union(p.declared_identifiers)
- self.listener.undeclared_identifiers = self.listener.undeclared_identifiers.union(p.undeclared_identifiers)
+ self.listener.declared_identifiers = \
+ self.listener.declared_identifiers.union(p.declared_identifiers)
+ self.listener.undeclared_identifiers = \
+ self.listener.undeclared_identifiers.union(p.undeclared_identifiers)
+
def visit(self, expr):
- visitor.walk(expr, self) #, walker=walker())
+ visitor.walk(expr, self) # , walker=walker())
+
class ParseFunc(object):
+
def __init__(self, listener, **exception_kwargs):
self.listener = listener
self.exception_kwargs = exception_kwargs
+
def visitFunction(self, node, *args):
self.listener.funcname = node.name
self.listener.argnames = node.argnames
self.listener.defaults = node.defaults
self.listener.varargs = node.varargs
self.listener.kwargs = node.kwargs
+
def visit(self, expr):
visitor.walk(expr, self)
+
class ExpressionGenerator(object):
- """given an AST node, generates an equivalent literal Python expression."""
+
+ """given an AST node, generates an equivalent literal Python
+ expression."""
+
def __init__(self, astnode):
self.buf = StringIO()
- visitor.walk(astnode, self) #, walker=walker())
+ visitor.walk(astnode, self) # , walker=walker())
+
def value(self):
- return self.buf.getvalue()
+ return self.buf.getvalue()
+
def operator(self, op, node, *args):
- self.buf.write("(")
+ self.buf.write('(')
self.visit(node.left, *args)
- self.buf.write(" %s " % op)
+ self.buf.write(' %s ' % op)
self.visit(node.right, *args)
- self.buf.write(")")
+ self.buf.write(')')
+
def booleanop(self, op, node, *args):
self.visit(node.nodes[0])
for n in node.nodes[1:]:
- self.buf.write(" " + op + " ")
+ self.buf.write(' ' + op + ' ')
self.visit(n, *args)
+
def visitConst(self, node, *args):
self.buf.write(repr(node.value))
+
def visitAssName(self, node, *args):
+
# TODO: figure out OP_ASSIGN, other OP_s
+
self.buf.write(node.name)
+
def visitName(self, node, *args):
self.buf.write(node.name)
+
def visitMul(self, node, *args):
- self.operator("*", node, *args)
+ self.operator('*', node, *args)
+
def visitAnd(self, node, *args):
- self.booleanop("and", node, *args)
+ self.booleanop('and', node, *args)
+
def visitOr(self, node, *args):
- self.booleanop("or", node, *args)
+ self.booleanop('or', node, *args)
+
def visitBitand(self, node, *args):
- self.booleanop("&", node, *args)
+ self.booleanop('&', node, *args)
+
def visitBitor(self, node, *args):
- self.booleanop("|", node, *args)
+ self.booleanop('|', node, *args)
+
def visitBitxor(self, node, *args):
- self.booleanop("^", node, *args)
+ self.booleanop('^', node, *args)
+
def visitAdd(self, node, *args):
- self.operator("+", node, *args)
+ self.operator('+', node, *args)
+
def visitGetattr(self, node, *args):
self.visit(node.expr, *args)
- self.buf.write(".%s" % node.attrname)
+ self.buf.write('.%s' % node.attrname)
+
def visitSub(self, node, *args):
- self.operator("-", node, *args)
+ self.operator('-', node, *args)
+
def visitNot(self, node, *args):
- self.buf.write("not ")
+ self.buf.write('not ')
self.visit(node.expr)
+
def visitDiv(self, node, *args):
- self.operator("/", node, *args)
+ self.operator('/', node, *args)
+
def visitFloorDiv(self, node, *args):
- self.operator("//", node, *args)
+ self.operator('//', node, *args)
+
def visitSubscript(self, node, *args):
self.visit(node.expr)
- self.buf.write("[")
+ self.buf.write('[')
[self.visit(x) for x in node.subs]
- self.buf.write("]")
+ self.buf.write(']')
+
def visitUnarySub(self, node, *args):
- self.buf.write("-")
+ self.buf.write('-')
self.visit(node.expr)
+
def visitUnaryAdd(self, node, *args):
- self.buf.write("-")
+ self.buf.write('-')
self.visit(node.expr)
+
def visitSlice(self, node, *args):
self.visit(node.expr)
- self.buf.write("[")
+ self.buf.write('[')
if node.lower is not None:
self.visit(node.lower)
- self.buf.write(":")
+ self.buf.write(':')
if node.upper is not None:
self.visit(node.upper)
- self.buf.write("]")
+ self.buf.write(']')
+
def visitDict(self, node):
- self.buf.write("{")
+ self.buf.write('{')
c = node.getChildren()
for i in range(0, len(c), 2):
self.visit(c[i])
- self.buf.write(": ")
- self.visit(c[i+1])
- if i<len(c) -2:
- self.buf.write(", ")
- self.buf.write("}")
+ self.buf.write(': ')
+ self.visit(c[i + 1])
+ if i < len(c) - 2:
+ self.buf.write(', ')
+ self.buf.write('}')
+
def visitTuple(self, node):
- self.buf.write("(")
+ self.buf.write('(')
c = node.getChildren()
for i in range(0, len(c)):
self.visit(c[i])
- if i<len(c) - 1:
- self.buf.write(", ")
- self.buf.write(")")
+ if i < len(c) - 1:
+ self.buf.write(', ')
+ self.buf.write(')')
+
def visitList(self, node):
- self.buf.write("[")
+ self.buf.write('[')
c = node.getChildren()
for i in range(0, len(c)):
self.visit(c[i])
- if i<len(c) - 1:
- self.buf.write(", ")
- self.buf.write("]")
+ if i < len(c) - 1:
+ self.buf.write(', ')
+ self.buf.write(']')
+
def visitListComp(self, node):
- self.buf.write("[")
+ self.buf.write('[')
self.visit(node.expr)
- self.buf.write(" ")
+ self.buf.write(' ')
for n in node.quals:
self.visit(n)
- self.buf.write("]")
+ self.buf.write(']')
+
def visitListCompFor(self, node):
- self.buf.write(" for ")
+ self.buf.write(' for ')
self.visit(node.assign)
- self.buf.write(" in ")
+ self.buf.write(' in ')
self.visit(node.list)
for n in node.ifs:
self.visit(n)
+
def visitListCompIf(self, node):
- self.buf.write(" if ")
+ self.buf.write(' if ')
self.visit(node.test)
+
def visitCompare(self, node):
self.visit(node.expr)
for tup in node.ops:
self.buf.write(tup[0])
self.visit(tup[1])
+
def visitCallFunc(self, node, *args):
self.visit(node.node)
- self.buf.write("(")
+ self.buf.write('(')
if len(node.args):
self.visit(node.args[0])
for a in node.args[1:]:
- self.buf.write(", ")
+ self.buf.write(', ')
self.visit(a)
- self.buf.write(")")
+ self.buf.write(')')
+
class walker(visitor.ASTVisitor):
+
def dispatch(self, node, *args):
- print "Node:", str(node)
- #print "dir:", dir(node)
+ print 'Node:', str(node)
+
+ # print "dir:", dir(node)
+
return visitor.ASTVisitor.dispatch(self, node, *args)