diff options
author | Anthony Baxter <anthonybaxter@gmail.com> | 2004-08-02 06:10:11 (GMT) |
---|---|---|
committer | Anthony Baxter <anthonybaxter@gmail.com> | 2004-08-02 06:10:11 (GMT) |
commit | c2a5a636545a88f349dbe3e452ffb4494b68e534 (patch) | |
tree | aaa24074dcdcce5afa51523969971bdd05381b01 /Lib | |
parent | fd7dc5169c3ca7d64109512f38762c4ce9e96c5f (diff) | |
download | cpython-c2a5a636545a88f349dbe3e452ffb4494b68e534.zip cpython-c2a5a636545a88f349dbe3e452ffb4494b68e534.tar.gz cpython-c2a5a636545a88f349dbe3e452ffb4494b68e534.tar.bz2 |
PEP-0318, @decorator-style. In Guido's words:
"@ seems the syntax that everybody can hate equally"
Implementation by Mark Russell, from SF #979728.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/compiler/ast.py | 1281 | ||||
-rw-r--r-- | Lib/compiler/pycodegen.py | 10 | ||||
-rw-r--r-- | Lib/compiler/symbols.py | 2 | ||||
-rw-r--r-- | Lib/compiler/transformer.py | 66 | ||||
-rw-r--r-- | Lib/pyclbr.py | 2 | ||||
-rwxr-xr-x | Lib/symbol.py | 140 | ||||
-rw-r--r-- | Lib/test/output/test_tokenize | 13 | ||||
-rw-r--r-- | Lib/test/pyclbr_input.py | 33 | ||||
-rw-r--r-- | Lib/test/test_decorators.py | 194 | ||||
-rw-r--r-- | Lib/test/test_parser.py | 12 | ||||
-rw-r--r-- | Lib/test/test_pyclbr.py | 44 | ||||
-rw-r--r-- | Lib/test/tokenize_tests.txt | 3 | ||||
-rwxr-xr-x | Lib/token.py | 7 | ||||
-rw-r--r-- | Lib/tokenize.py | 2 |
14 files changed, 1084 insertions, 725 deletions
diff --git a/Lib/compiler/ast.py b/Lib/compiler/ast.py index 064df50..a81937f 100644 --- a/Lib/compiler/ast.py +++ b/Lib/compiler/ast.py @@ -48,132 +48,181 @@ class Node: # an abstract base class class EmptyNode(Node): pass -class Slice(Node): - nodes["slice"] = "Slice" - def __init__(self, expr, flags, lower, upper): +class Expression(Node): + # Expression is an artificial node class to support "eval" + nodes["expression"] = "Expression" + def __init__(self, node): + self.node = node + + def getChildren(self): + return self.node, + + def getChildNodes(self): + return self.node, + + def __repr__(self): + return "Expression(%s)" % (repr(self.node)) + +class Add(Node): + nodes["add"] = "Add" + def __init__(self, (left, right)): + self.left = left + self.right = right + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Add((%s, %s))" % (repr(self.left), repr(self.right)) + +class And(Node): + nodes["and"] = "And" + def __init__(self, nodes): + self.nodes = nodes + + def getChildren(self): + children = [] + children.extend(flatten(self.nodes)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "And(%s)" % (repr(self.nodes),) + +class AssAttr(Node): + nodes["assattr"] = "AssAttr" + def __init__(self, expr, attrname, flags): self.expr = expr + self.attrname = attrname self.flags = flags - self.lower = lower - self.upper = upper + + def getChildren(self): + return self.expr, self.attrname, self.flags + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) + +class AssList(Node): + nodes["asslist"] = "AssList" + def __init__(self, nodes): + self.nodes = nodes def getChildren(self): children = [] - children.append(self.expr) - children.append(self.flags) - children.append(self.lower) - children.append(self.upper) + children.extend(flatten(self.nodes)) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.append(self.expr) - if self.lower is not None: nodelist.append(self.lower) - if self.upper is not None: nodelist.append(self.upper) + nodelist.extend(flatten_nodes(self.nodes)) return tuple(nodelist) def __repr__(self): - return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) + return "AssList(%s)" % (repr(self.nodes),) -class Const(Node): - nodes["const"] = "Const" - def __init__(self, value): - self.value = value +class AssName(Node): + nodes["assname"] = "AssName" + def __init__(self, name, flags): + self.name = name + self.flags = flags def getChildren(self): - return self.value, + return self.name, self.flags def getChildNodes(self): return () def __repr__(self): - return "Const(%s)" % (repr(self.value),) + return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) -class Raise(Node): - nodes["raise"] = "Raise" - def __init__(self, expr1, expr2, expr3): - self.expr1 = expr1 - self.expr2 = expr2 - self.expr3 = expr3 +class AssTuple(Node): + nodes["asstuple"] = "AssTuple" + def __init__(self, nodes): + self.nodes = nodes def getChildren(self): children = [] - children.append(self.expr1) - children.append(self.expr2) - children.append(self.expr3) + children.extend(flatten(self.nodes)) return tuple(children) def getChildNodes(self): nodelist = [] - if self.expr1 is not None: nodelist.append(self.expr1) - if self.expr2 is not None: nodelist.append(self.expr2) - if self.expr3 is not None: nodelist.append(self.expr3) + nodelist.extend(flatten_nodes(self.nodes)) return tuple(nodelist) def __repr__(self): - return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) + return "AssTuple(%s)" % (repr(self.nodes),) -class For(Node): - nodes["for"] = "For" - def __init__(self, assign, list, body, else_): - self.assign = assign - self.list = list - self.body = body - self.else_ = else_ +class Assert(Node): + nodes["assert"] = "Assert" + def __init__(self, test, fail): + self.test = test + self.fail = fail def getChildren(self): children = [] - children.append(self.assign) - children.append(self.list) - children.append(self.body) - children.append(self.else_) + children.append(self.test) + children.append(self.fail) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.append(self.assign) - nodelist.append(self.list) - nodelist.append(self.body) - if self.else_ is not None: nodelist.append(self.else_) + nodelist.append(self.test) + if self.fail is not None: nodelist.append(self.fail) return tuple(nodelist) def __repr__(self): - return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) + return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) -class AssTuple(Node): - nodes["asstuple"] = "AssTuple" - def __init__(self, nodes): +class Assign(Node): + nodes["assign"] = "Assign" + def __init__(self, nodes, expr): self.nodes = nodes + self.expr = expr def getChildren(self): children = [] children.extend(flatten(self.nodes)) + children.append(self.expr) return tuple(children) def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) + nodelist.append(self.expr) return tuple(nodelist) def __repr__(self): - return "AssTuple(%s)" % (repr(self.nodes),) + return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) -class Mul(Node): - nodes["mul"] = "Mul" - def __init__(self, (left, right)): - self.left = left - self.right = right +class AugAssign(Node): + nodes["augassign"] = "AugAssign" + def __init__(self, node, op, expr): + self.node = node + self.op = op + self.expr = expr def getChildren(self): - return self.left, self.right + return self.node, self.op, self.expr def getChildNodes(self): - return self.left, self.right + return self.node, self.expr def __repr__(self): - return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) + return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) -class Invert(Node): - nodes["invert"] = "Invert" +class Backquote(Node): + nodes["backquote"] = "Backquote" def __init__(self, expr): self.expr = expr @@ -184,25 +233,28 @@ class Invert(Node): return self.expr, def __repr__(self): - return "Invert(%s)" % (repr(self.expr),) + return "Backquote(%s)" % (repr(self.expr),) -class RightShift(Node): - nodes["rightshift"] = "RightShift" - def __init__(self, (left, right)): - self.left = left - self.right = right +class Bitand(Node): + nodes["bitand"] = "Bitand" + def __init__(self, nodes): + self.nodes = nodes def getChildren(self): - return self.left, self.right + children = [] + children.extend(flatten(self.nodes)) + return tuple(children) def getChildNodes(self): - return self.left, self.right + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) def __repr__(self): - return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) + return "Bitand(%s)" % (repr(self.nodes),) -class AssList(Node): - nodes["asslist"] = "AssList" +class Bitor(Node): + nodes["bitor"] = "Bitor" def __init__(self, nodes): self.nodes = nodes @@ -217,102 +269,129 @@ class AssList(Node): return tuple(nodelist) def __repr__(self): - return "AssList(%s)" % (repr(self.nodes),) + return "Bitor(%s)" % (repr(self.nodes),) -class From(Node): - nodes["from"] = "From" - def __init__(self, modname, names): - self.modname = modname - self.names = names +class Bitxor(Node): + nodes["bitxor"] = "Bitxor" + def __init__(self, nodes): + self.nodes = nodes def getChildren(self): - return self.modname, self.names + children = [] + children.extend(flatten(self.nodes)) + return tuple(children) def getChildNodes(self): - return () + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) def __repr__(self): - return "From(%s, %s)" % (repr(self.modname), repr(self.names)) + return "Bitxor(%s)" % (repr(self.nodes),) -class Getattr(Node): - nodes["getattr"] = "Getattr" - def __init__(self, expr, attrname): - self.expr = expr - self.attrname = attrname +class Break(Node): + nodes["break"] = "Break" + def __init__(self, ): + pass def getChildren(self): - return self.expr, self.attrname + return () def getChildNodes(self): - return self.expr, + return () def __repr__(self): - return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) + return "Break()" -class Dict(Node): - nodes["dict"] = "Dict" - def __init__(self, items): - self.items = items +class CallFunc(Node): + nodes["callfunc"] = "CallFunc" + def __init__(self, node, args, star_args = None, dstar_args = None): + self.node = node + self.args = args + self.star_args = star_args + self.dstar_args = dstar_args def getChildren(self): children = [] - children.extend(flatten(self.items)) + children.append(self.node) + children.extend(flatten(self.args)) + children.append(self.star_args) + children.append(self.dstar_args) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.items)) + nodelist.append(self.node) + nodelist.extend(flatten_nodes(self.args)) + if self.star_args is not None: nodelist.append(self.star_args) + if self.dstar_args is not None: nodelist.append(self.dstar_args) return tuple(nodelist) def __repr__(self): - return "Dict(%s)" % (repr(self.items),) + return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) -class Module(Node): - nodes["module"] = "Module" - def __init__(self, doc, node): +class Class(Node): + nodes["class"] = "Class" + def __init__(self, name, bases, doc, code): + self.name = name + self.bases = bases self.doc = doc - self.node = node + self.code = code def getChildren(self): - return self.doc, self.node + children = [] + children.append(self.name) + children.extend(flatten(self.bases)) + children.append(self.doc) + children.append(self.code) + return tuple(children) def getChildNodes(self): - return self.node, + nodelist = [] + nodelist.extend(flatten_nodes(self.bases)) + nodelist.append(self.code) + return tuple(nodelist) def __repr__(self): - return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) + return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code)) -class Expression(Node): - # Expression is an artificial node class to support "eval" - nodes["expression"] = "Expression" - def __init__(self, node): - self.node = node +class Compare(Node): + nodes["compare"] = "Compare" + def __init__(self, expr, ops): + self.expr = expr + self.ops = ops def getChildren(self): - return self.node, + children = [] + children.append(self.expr) + children.extend(flatten(self.ops)) + return tuple(children) def getChildNodes(self): - return self.node, + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.ops)) + return tuple(nodelist) def __repr__(self): - return "Expression(%s)" % (repr(self.node)) + return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) -class UnaryAdd(Node): - nodes["unaryadd"] = "UnaryAdd" - def __init__(self, expr): - self.expr = expr +class Const(Node): + nodes["const"] = "Const" + def __init__(self, value): + self.value = value def getChildren(self): - return self.expr, + return self.value, def getChildNodes(self): - return self.expr, + return () def __repr__(self): - return "UnaryAdd(%s)" % (repr(self.expr),) + return "Const(%s)" % (repr(self.value),) -class Ellipsis(Node): - nodes["ellipsis"] = "Ellipsis" +class Continue(Node): + nodes["continue"] = "Continue" def __init__(self, ): pass @@ -323,125 +402,168 @@ class Ellipsis(Node): return () def __repr__(self): - return "Ellipsis()" + return "Continue()" -class Print(Node): - nodes["print"] = "Print" - def __init__(self, nodes, dest): +class Decorators(Node): + nodes["decorators"] = "Decorators" + def __init__(self, nodes): self.nodes = nodes - self.dest = dest + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + return flatten_nodes(self.nodes) + + def __repr__(self): + return "Decorators(%s)" % (repr(self.nodes),) + +class Dict(Node): + nodes["dict"] = "Dict" + def __init__(self, items): + self.items = items def getChildren(self): children = [] - children.extend(flatten(self.nodes)) - children.append(self.dest) + children.extend(flatten(self.items)) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) - if self.dest is not None: nodelist.append(self.dest) + nodelist.extend(flatten_nodes(self.items)) return tuple(nodelist) def __repr__(self): - return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) + return "Dict(%s)" % (repr(self.items),) -class Import(Node): - nodes["import"] = "Import" - def __init__(self, names): - self.names = names +class Discard(Node): + nodes["discard"] = "Discard" + def __init__(self, expr): + self.expr = expr def getChildren(self): - return self.names, + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Discard(%s)" % (repr(self.expr),) + +class Div(Node): + nodes["div"] = "Div" + def __init__(self, (left, right)): + self.left = left + self.right = right + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Div((%s, %s))" % (repr(self.left), repr(self.right)) + +class Ellipsis(Node): + nodes["ellipsis"] = "Ellipsis" + def __init__(self, ): + pass + + def getChildren(self): + return () def getChildNodes(self): return () def __repr__(self): - return "Import(%s)" % (repr(self.names),) + return "Ellipsis()" -class Subscript(Node): - nodes["subscript"] = "Subscript" - def __init__(self, expr, flags, subs): +class Exec(Node): + nodes["exec"] = "Exec" + def __init__(self, expr, locals, globals): self.expr = expr - self.flags = flags - self.subs = subs + self.locals = locals + self.globals = globals def getChildren(self): children = [] children.append(self.expr) - children.append(self.flags) - children.extend(flatten(self.subs)) + children.append(self.locals) + children.append(self.globals) return tuple(children) def getChildNodes(self): nodelist = [] nodelist.append(self.expr) - nodelist.extend(flatten_nodes(self.subs)) + if self.locals is not None: nodelist.append(self.locals) + if self.globals is not None: nodelist.append(self.globals) return tuple(nodelist) def __repr__(self): - return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) + return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) -class TryExcept(Node): - nodes["tryexcept"] = "TryExcept" - def __init__(self, body, handlers, else_): - self.body = body - self.handlers = handlers - self.else_ = else_ +class FloorDiv(Node): + nodes["floordiv"] = "FloorDiv" + def __init__(self, (left, right)): + self.left = left + self.right = right def getChildren(self): - children = [] - children.append(self.body) - children.extend(flatten(self.handlers)) - children.append(self.else_) - return tuple(children) + return self.left, self.right def getChildNodes(self): - nodelist = [] - nodelist.append(self.body) - nodelist.extend(flatten_nodes(self.handlers)) - if self.else_ is not None: nodelist.append(self.else_) - return tuple(nodelist) + return self.left, self.right def __repr__(self): - return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) + return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) -class Or(Node): - nodes["or"] = "Or" - def __init__(self, nodes): - self.nodes = nodes +class For(Node): + nodes["for"] = "For" + def __init__(self, assign, list, body, else_): + self.assign = assign + self.list = list + self.body = body + self.else_ = else_ def getChildren(self): children = [] - children.extend(flatten(self.nodes)) + children.append(self.assign) + children.append(self.list) + children.append(self.body) + children.append(self.else_) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) + nodelist.append(self.assign) + nodelist.append(self.list) + nodelist.append(self.body) + if self.else_ is not None: nodelist.append(self.else_) return tuple(nodelist) def __repr__(self): - return "Or(%s)" % (repr(self.nodes),) + return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) -class Name(Node): - nodes["name"] = "Name" - def __init__(self, name): - self.name = name +class From(Node): + nodes["from"] = "From" + def __init__(self, modname, names): + self.modname = modname + self.names = names def getChildren(self): - return self.name, + return self.modname, self.names def getChildNodes(self): return () def __repr__(self): - return "Name(%s)" % (repr(self.name),) + return "From(%s, %s)" % (repr(self.modname), repr(self.names)) class Function(Node): nodes["function"] = "Function" - def __init__(self, name, argnames, defaults, flags, doc, code): + def __init__(self, decorators, name, argnames, defaults, flags, doc, code): + self.decorators = decorators self.name = name self.argnames = argnames self.defaults = defaults @@ -458,6 +580,8 @@ class Function(Node): def getChildren(self): children = [] + if self.decorators: + children.append(flatten(self.decorators.nodes)) children.append(self.name) children.append(self.argnames) children.extend(flatten(self.defaults)) @@ -468,226 +592,221 @@ class Function(Node): def getChildNodes(self): nodelist = [] + if self.decorators: + nodelist.extend(flatten_nodes(self.decorators.nodes)) nodelist.extend(flatten_nodes(self.defaults)) nodelist.append(self.code) return tuple(nodelist) def __repr__(self): - return "Function(%s, %s, %s, %s, %s, %s)" % (repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) + return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) + +class GenExpr(Node): + nodes["genexpr"] = "GenExpr" + def __init__(self, code): + self.code = code + self.argnames = ['[outmost-iterable]'] + self.varargs = self.kwargs = None + -class Assert(Node): - nodes["assert"] = "Assert" - def __init__(self, test, fail): - self.test = test - self.fail = fail def getChildren(self): - children = [] - children.append(self.test) - children.append(self.fail) - return tuple(children) + return self.code, def getChildNodes(self): - nodelist = [] - nodelist.append(self.test) - if self.fail is not None: nodelist.append(self.fail) - return tuple(nodelist) + return self.code, def __repr__(self): - return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) + return "GenExpr(%s)" % (repr(self.code),) + +class GenExprFor(Node): + nodes["genexprfor"] = "GenExprFor" + def __init__(self, assign, iter, ifs): + self.assign = assign + self.iter = iter + self.ifs = ifs + self.is_outmost = False -class Return(Node): - nodes["return"] = "Return" - def __init__(self, value): - self.value = value def getChildren(self): - return self.value, + children = [] + children.append(self.assign) + children.append(self.iter) + children.extend(flatten(self.ifs)) + return tuple(children) def getChildNodes(self): - return self.value, + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.iter) + nodelist.extend(flatten_nodes(self.ifs)) + return tuple(nodelist) def __repr__(self): - return "Return(%s)" % (repr(self.value),) + return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) -class Power(Node): - nodes["power"] = "Power" - def __init__(self, (left, right)): - self.left = left - self.right = right +class GenExprIf(Node): + nodes["genexprif"] = "GenExprIf" + def __init__(self, test): + self.test = test def getChildren(self): - return self.left, self.right + return self.test, def getChildNodes(self): - return self.left, self.right + return self.test, def __repr__(self): - return "Power((%s, %s))" % (repr(self.left), repr(self.right)) + return "GenExprIf(%s)" % (repr(self.test),) -class Exec(Node): - nodes["exec"] = "Exec" - def __init__(self, expr, locals, globals): +class GenExprInner(Node): + nodes["genexprinner"] = "GenExprInner" + def __init__(self, expr, quals): self.expr = expr - self.locals = locals - self.globals = globals + self.quals = quals def getChildren(self): children = [] children.append(self.expr) - children.append(self.locals) - children.append(self.globals) + children.extend(flatten(self.quals)) return tuple(children) def getChildNodes(self): nodelist = [] nodelist.append(self.expr) - if self.locals is not None: nodelist.append(self.locals) - if self.globals is not None: nodelist.append(self.globals) - return tuple(nodelist) - - def __repr__(self): - return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) - -class Stmt(Node): - nodes["stmt"] = "Stmt" - def __init__(self, nodes): - self.nodes = nodes - - def getChildren(self): - children = [] - children.extend(flatten(self.nodes)) - return tuple(children) - - def getChildNodes(self): - nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) + nodelist.extend(flatten_nodes(self.quals)) return tuple(nodelist) def __repr__(self): - return "Stmt(%s)" % (repr(self.nodes),) + return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) -class Sliceobj(Node): - nodes["sliceobj"] = "Sliceobj" - def __init__(self, nodes): - self.nodes = nodes +class Getattr(Node): + nodes["getattr"] = "Getattr" + def __init__(self, expr, attrname): + self.expr = expr + self.attrname = attrname def getChildren(self): - children = [] - children.extend(flatten(self.nodes)) - return tuple(children) + return self.expr, self.attrname def getChildNodes(self): - nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return self.expr, def __repr__(self): - return "Sliceobj(%s)" % (repr(self.nodes),) + return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) -class Break(Node): - nodes["break"] = "Break" - def __init__(self, ): - pass +class Global(Node): + nodes["global"] = "Global" + def __init__(self, names): + self.names = names def getChildren(self): - return () + return self.names, def getChildNodes(self): return () def __repr__(self): - return "Break()" + return "Global(%s)" % (repr(self.names),) -class Bitand(Node): - nodes["bitand"] = "Bitand" - def __init__(self, nodes): - self.nodes = nodes +class If(Node): + nodes["if"] = "If" + def __init__(self, tests, else_): + self.tests = tests + self.else_ = else_ def getChildren(self): children = [] - children.extend(flatten(self.nodes)) + children.extend(flatten(self.tests)) + children.append(self.else_) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) + nodelist.extend(flatten_nodes(self.tests)) + if self.else_ is not None: nodelist.append(self.else_) return tuple(nodelist) def __repr__(self): - return "Bitand(%s)" % (repr(self.nodes),) + return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) -class FloorDiv(Node): - nodes["floordiv"] = "FloorDiv" - def __init__(self, (left, right)): - self.left = left - self.right = right +class Import(Node): + nodes["import"] = "Import" + def __init__(self, names): + self.names = names def getChildren(self): - return self.left, self.right + return self.names, def getChildNodes(self): - return self.left, self.right + return () def __repr__(self): - return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) + return "Import(%s)" % (repr(self.names),) -class TryFinally(Node): - nodes["tryfinally"] = "TryFinally" - def __init__(self, body, final): - self.body = body - self.final = final +class Invert(Node): + nodes["invert"] = "Invert" + def __init__(self, expr): + self.expr = expr def getChildren(self): - return self.body, self.final + return self.expr, def getChildNodes(self): - return self.body, self.final + return self.expr, def __repr__(self): - return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) + return "Invert(%s)" % (repr(self.expr),) -class Not(Node): - nodes["not"] = "Not" - def __init__(self, expr): +class Keyword(Node): + nodes["keyword"] = "Keyword" + def __init__(self, name, expr): + self.name = name self.expr = expr def getChildren(self): - return self.expr, + return self.name, self.expr def getChildNodes(self): return self.expr, def __repr__(self): - return "Not(%s)" % (repr(self.expr),) + return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) -class Class(Node): - nodes["class"] = "Class" - def __init__(self, name, bases, doc, code): - self.name = name - self.bases = bases - self.doc = doc +class Lambda(Node): + nodes["lambda"] = "Lambda" + def __init__(self, argnames, defaults, flags, code): + self.argnames = argnames + self.defaults = defaults + self.flags = flags self.code = code + self.varargs = self.kwargs = None + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 + + def getChildren(self): children = [] - children.append(self.name) - children.extend(flatten(self.bases)) - children.append(self.doc) + children.append(self.argnames) + children.extend(flatten(self.defaults)) + children.append(self.flags) children.append(self.code) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.bases)) + nodelist.extend(flatten_nodes(self.defaults)) nodelist.append(self.code) return tuple(nodelist) def __repr__(self): - return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code)) + return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) -class Mod(Node): - nodes["mod"] = "Mod" +class LeftShift(Node): + nodes["leftshift"] = "LeftShift" def __init__(self, (left, right)): self.left = left self.right = right @@ -699,128 +818,117 @@ class Mod(Node): return self.left, self.right def __repr__(self): - return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) + return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) -class Printnl(Node): - nodes["printnl"] = "Printnl" - def __init__(self, nodes, dest): +class List(Node): + nodes["list"] = "List" + def __init__(self, nodes): self.nodes = nodes - self.dest = dest def getChildren(self): children = [] children.extend(flatten(self.nodes)) - children.append(self.dest) return tuple(children) def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - if self.dest is not None: nodelist.append(self.dest) return tuple(nodelist) def __repr__(self): - return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) + return "List(%s)" % (repr(self.nodes),) -class Tuple(Node): - nodes["tuple"] = "Tuple" - def __init__(self, nodes): - self.nodes = nodes +class ListComp(Node): + nodes["listcomp"] = "ListComp" + def __init__(self, expr, quals): + self.expr = expr + self.quals = quals def getChildren(self): children = [] - children.extend(flatten(self.nodes)) + children.append(self.expr) + children.extend(flatten(self.quals)) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.quals)) return tuple(nodelist) def __repr__(self): - return "Tuple(%s)" % (repr(self.nodes),) - -class AssAttr(Node): - nodes["assattr"] = "AssAttr" - def __init__(self, expr, attrname, flags): - self.expr = expr - self.attrname = attrname - self.flags = flags - - def getChildren(self): - return self.expr, self.attrname, self.flags - - def getChildNodes(self): - return self.expr, - - def __repr__(self): - return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) + return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) -class Keyword(Node): - nodes["keyword"] = "Keyword" - def __init__(self, name, expr): - self.name = name - self.expr = expr +class ListCompFor(Node): + nodes["listcompfor"] = "ListCompFor" + def __init__(self, assign, list, ifs): + self.assign = assign + self.list = list + self.ifs = ifs def getChildren(self): - return self.name, self.expr + children = [] + children.append(self.assign) + children.append(self.list) + children.extend(flatten(self.ifs)) + return tuple(children) def getChildNodes(self): - return self.expr, + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.list) + nodelist.extend(flatten_nodes(self.ifs)) + return tuple(nodelist) def __repr__(self): - return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) + return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) -class AugAssign(Node): - nodes["augassign"] = "AugAssign" - def __init__(self, node, op, expr): - self.node = node - self.op = op - self.expr = expr +class ListCompIf(Node): + nodes["listcompif"] = "ListCompIf" + def __init__(self, test): + self.test = test def getChildren(self): - return self.node, self.op, self.expr + return self.test, def getChildNodes(self): - return self.node, self.expr + return self.test, def __repr__(self): - return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) + return "ListCompIf(%s)" % (repr(self.test),) -class List(Node): - nodes["list"] = "List" - def __init__(self, nodes): - self.nodes = nodes +class Mod(Node): + nodes["mod"] = "Mod" + def __init__(self, (left, right)): + self.left = left + self.right = right def getChildren(self): - children = [] - children.extend(flatten(self.nodes)) - return tuple(children) + return self.left, self.right def getChildNodes(self): - nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return self.left, self.right def __repr__(self): - return "List(%s)" % (repr(self.nodes),) + return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) -class Yield(Node): - nodes["yield"] = "Yield" - def __init__(self, value): - self.value = value +class Module(Node): + nodes["module"] = "Module" + def __init__(self, doc, node): + self.doc = doc + self.node = node def getChildren(self): - return self.value, + return self.doc, self.node def getChildNodes(self): - return self.value, + return self.node, def __repr__(self): - return "Yield(%s)" % (repr(self.value),) + return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) -class LeftShift(Node): - nodes["leftshift"] = "LeftShift" +class Mul(Node): + nodes["mul"] = "Mul" def __init__(self, (left, right)): self.left = left self.right = right @@ -832,49 +940,56 @@ class LeftShift(Node): return self.left, self.right def __repr__(self): - return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) + return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) -class AssName(Node): - nodes["assname"] = "AssName" - def __init__(self, name, flags): +class Name(Node): + nodes["name"] = "Name" + def __init__(self, name): self.name = name - self.flags = flags def getChildren(self): - return self.name, self.flags + return self.name, def getChildNodes(self): return () def __repr__(self): - return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) + return "Name(%s)" % (repr(self.name),) -class While(Node): - nodes["while"] = "While" - def __init__(self, test, body, else_): - self.test = test - self.body = body - self.else_ = else_ +class Not(Node): + nodes["not"] = "Not" + def __init__(self, expr): + self.expr = expr + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Not(%s)" % (repr(self.expr),) + +class Or(Node): + nodes["or"] = "Or" + def __init__(self, nodes): + self.nodes = nodes def getChildren(self): children = [] - children.append(self.test) - children.append(self.body) - children.append(self.else_) + children.extend(flatten(self.nodes)) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.append(self.test) - nodelist.append(self.body) - if self.else_ is not None: nodelist.append(self.else_) + nodelist.extend(flatten_nodes(self.nodes)) return tuple(nodelist) def __repr__(self): - return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) + return "Or(%s)" % (repr(self.nodes),) -class Continue(Node): - nodes["continue"] = "Continue" +class Pass(Node): + nodes["pass"] = "Pass" def __init__(self, ): pass @@ -885,38 +1000,10 @@ class Continue(Node): return () def __repr__(self): - return "Continue()" - -class Backquote(Node): - nodes["backquote"] = "Backquote" - def __init__(self, expr): - self.expr = expr - - def getChildren(self): - return self.expr, - - def getChildNodes(self): - return self.expr, - - def __repr__(self): - return "Backquote(%s)" % (repr(self.expr),) - -class Discard(Node): - nodes["discard"] = "Discard" - def __init__(self, expr): - self.expr = expr - - def getChildren(self): - return self.expr, - - def getChildNodes(self): - return self.expr, - - def __repr__(self): - return "Discard(%s)" % (repr(self.expr),) + return "Pass()" -class Div(Node): - nodes["div"] = "Div" +class Power(Node): + nodes["power"] = "Power" def __init__(self, (left, right)): self.left = left self.right = right @@ -928,119 +1015,131 @@ class Div(Node): return self.left, self.right def __repr__(self): - return "Div((%s, %s))" % (repr(self.left), repr(self.right)) + return "Power((%s, %s))" % (repr(self.left), repr(self.right)) -class Assign(Node): - nodes["assign"] = "Assign" - def __init__(self, nodes, expr): +class Print(Node): + nodes["print"] = "Print" + def __init__(self, nodes, dest): self.nodes = nodes - self.expr = expr + self.dest = dest def getChildren(self): children = [] children.extend(flatten(self.nodes)) - children.append(self.expr) + children.append(self.dest) return tuple(children) def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - nodelist.append(self.expr) + if self.dest is not None: nodelist.append(self.dest) return tuple(nodelist) def __repr__(self): - return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) - -class Lambda(Node): - nodes["lambda"] = "Lambda" - def __init__(self, argnames, defaults, flags, code): - self.argnames = argnames - self.defaults = defaults - self.flags = flags - self.code = code - self.varargs = self.kwargs = None - if flags & CO_VARARGS: - self.varargs = 1 - if flags & CO_VARKEYWORDS: - self.kwargs = 1 + return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) +class Printnl(Node): + nodes["printnl"] = "Printnl" + def __init__(self, nodes, dest): + self.nodes = nodes + self.dest = dest def getChildren(self): children = [] - children.append(self.argnames) - children.extend(flatten(self.defaults)) - children.append(self.flags) - children.append(self.code) + children.extend(flatten(self.nodes)) + children.append(self.dest) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.defaults)) - nodelist.append(self.code) + nodelist.extend(flatten_nodes(self.nodes)) + if self.dest is not None: nodelist.append(self.dest) return tuple(nodelist) def __repr__(self): - return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) + return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) -class And(Node): - nodes["and"] = "And" - def __init__(self, nodes): - self.nodes = nodes +class Raise(Node): + nodes["raise"] = "Raise" + def __init__(self, expr1, expr2, expr3): + self.expr1 = expr1 + self.expr2 = expr2 + self.expr3 = expr3 def getChildren(self): children = [] - children.extend(flatten(self.nodes)) + children.append(self.expr1) + children.append(self.expr2) + children.append(self.expr3) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) + if self.expr1 is not None: nodelist.append(self.expr1) + if self.expr2 is not None: nodelist.append(self.expr2) + if self.expr3 is not None: nodelist.append(self.expr3) return tuple(nodelist) def __repr__(self): - return "And(%s)" % (repr(self.nodes),) + return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) -class Compare(Node): - nodes["compare"] = "Compare" - def __init__(self, expr, ops): - self.expr = expr - self.ops = ops +class Return(Node): + nodes["return"] = "Return" + def __init__(self, value): + self.value = value def getChildren(self): - children = [] - children.append(self.expr) - children.extend(flatten(self.ops)) - return tuple(children) + return self.value, def getChildNodes(self): - nodelist = [] - nodelist.append(self.expr) - nodelist.extend(flatten_nodes(self.ops)) - return tuple(nodelist) + return self.value, def __repr__(self): - return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) + return "Return(%s)" % (repr(self.value),) -class Bitor(Node): - nodes["bitor"] = "Bitor" - def __init__(self, nodes): - self.nodes = nodes +class RightShift(Node): + nodes["rightshift"] = "RightShift" + def __init__(self, (left, right)): + self.left = left + self.right = right + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) + +class Slice(Node): + nodes["slice"] = "Slice" + def __init__(self, expr, flags, lower, upper): + self.expr = expr + self.flags = flags + self.lower = lower + self.upper = upper def getChildren(self): children = [] - children.extend(flatten(self.nodes)) + children.append(self.expr) + children.append(self.flags) + children.append(self.lower) + children.append(self.upper) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.nodes)) + nodelist.append(self.expr) + if self.lower is not None: nodelist.append(self.lower) + if self.upper is not None: nodelist.append(self.upper) return tuple(nodelist) def __repr__(self): - return "Bitor(%s)" % (repr(self.nodes),) + return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) -class Bitxor(Node): - nodes["bitxor"] = "Bitxor" +class Sliceobj(Node): + nodes["sliceobj"] = "Sliceobj" def __init__(self, nodes): self.nodes = nodes @@ -1055,77 +1154,25 @@ class Bitxor(Node): return tuple(nodelist) def __repr__(self): - return "Bitxor(%s)" % (repr(self.nodes),) + return "Sliceobj(%s)" % (repr(self.nodes),) -class CallFunc(Node): - nodes["callfunc"] = "CallFunc" - def __init__(self, node, args, star_args = None, dstar_args = None): - self.node = node - self.args = args - self.star_args = star_args - self.dstar_args = dstar_args +class Stmt(Node): + nodes["stmt"] = "Stmt" + def __init__(self, nodes): + self.nodes = nodes def getChildren(self): children = [] - children.append(self.node) - children.extend(flatten(self.args)) - children.append(self.star_args) - children.append(self.dstar_args) + children.extend(flatten(self.nodes)) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.append(self.node) - nodelist.extend(flatten_nodes(self.args)) - if self.star_args is not None: nodelist.append(self.star_args) - if self.dstar_args is not None: nodelist.append(self.dstar_args) + nodelist.extend(flatten_nodes(self.nodes)) return tuple(nodelist) def __repr__(self): - return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) - -class Global(Node): - nodes["global"] = "Global" - def __init__(self, names): - self.names = names - - def getChildren(self): - return self.names, - - def getChildNodes(self): - return () - - def __repr__(self): - return "Global(%s)" % (repr(self.names),) - -class Add(Node): - nodes["add"] = "Add" - def __init__(self, (left, right)): - self.left = left - self.right = right - - def getChildren(self): - return self.left, self.right - - def getChildNodes(self): - return self.left, self.right - - def __repr__(self): - return "Add((%s, %s))" % (repr(self.left), repr(self.right)) - -class ListCompIf(Node): - nodes["listcompif"] = "ListCompIf" - def __init__(self, test): - self.test = test - - def getChildren(self): - return self.test, - - def getChildNodes(self): - return self.test, - - def __repr__(self): - return "ListCompIf(%s)" % (repr(self.test),) + return "Stmt(%s)" % (repr(self.nodes),) class Sub(Node): nodes["sub"] = "Sub" @@ -1142,175 +1189,151 @@ class Sub(Node): def __repr__(self): return "Sub((%s, %s))" % (repr(self.left), repr(self.right)) -class Pass(Node): - nodes["pass"] = "Pass" - def __init__(self, ): - pass - - def getChildren(self): - return () - - def getChildNodes(self): - return () - - def __repr__(self): - return "Pass()" - -class UnarySub(Node): - nodes["unarysub"] = "UnarySub" - def __init__(self, expr): +class Subscript(Node): + nodes["subscript"] = "Subscript" + def __init__(self, expr, flags, subs): self.expr = expr + self.flags = flags + self.subs = subs def getChildren(self): - return self.expr, + children = [] + children.append(self.expr) + children.append(self.flags) + children.extend(flatten(self.subs)) + return tuple(children) def getChildNodes(self): - return self.expr, + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.subs)) + return tuple(nodelist) def __repr__(self): - return "UnarySub(%s)" % (repr(self.expr),) + return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) -class If(Node): - nodes["if"] = "If" - def __init__(self, tests, else_): - self.tests = tests +class TryExcept(Node): + nodes["tryexcept"] = "TryExcept" + def __init__(self, body, handlers, else_): + self.body = body + self.handlers = handlers self.else_ = else_ def getChildren(self): children = [] - children.extend(flatten(self.tests)) + children.append(self.body) + children.extend(flatten(self.handlers)) children.append(self.else_) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.extend(flatten_nodes(self.tests)) + nodelist.append(self.body) + nodelist.extend(flatten_nodes(self.handlers)) if self.else_ is not None: nodelist.append(self.else_) return tuple(nodelist) def __repr__(self): - return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) + return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) -class ListComp(Node): - nodes["listcomp"] = "ListComp" - def __init__(self, expr, quals): - self.expr = expr - self.quals = quals +class TryFinally(Node): + nodes["tryfinally"] = "TryFinally" + def __init__(self, body, final): + self.body = body + self.final = final def getChildren(self): - children = [] - children.append(self.expr) - children.extend(flatten(self.quals)) - return tuple(children) + return self.body, self.final def getChildNodes(self): - nodelist = [] - nodelist.append(self.expr) - nodelist.extend(flatten_nodes(self.quals)) - return tuple(nodelist) + return self.body, self.final def __repr__(self): - return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) + return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) -class ListCompFor(Node): - nodes["listcompfor"] = "ListCompFor" - def __init__(self, assign, list, ifs): - self.assign = assign - self.list = list - self.ifs = ifs +class Tuple(Node): + nodes["tuple"] = "Tuple" + def __init__(self, nodes): + self.nodes = nodes def getChildren(self): children = [] - children.append(self.assign) - children.append(self.list) - children.extend(flatten(self.ifs)) + children.extend(flatten(self.nodes)) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.append(self.assign) - nodelist.append(self.list) - nodelist.extend(flatten_nodes(self.ifs)) + nodelist.extend(flatten_nodes(self.nodes)) return tuple(nodelist) def __repr__(self): - return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) + return "Tuple(%s)" % (repr(self.nodes),) -class GenExpr(Node): - nodes["genexpr"] = "GenExpr" - def __init__(self, code): - self.code = code - self.argnames = ['[outmost-iterable]'] - self.varargs = self.kwargs = None +class UnaryAdd(Node): + nodes["unaryadd"] = "UnaryAdd" + def __init__(self, expr): + self.expr = expr def getChildren(self): - return self.code, + return self.expr, def getChildNodes(self): - return self.code, + return self.expr, def __repr__(self): - return "GenExpr(%s)" % (repr(self.code),) + return "UnaryAdd(%s)" % (repr(self.expr),) -class GenExprInner(Node): - nodes["genexprinner"] = "GenExprInner" - def __init__(self, expr, quals): +class UnarySub(Node): + nodes["unarysub"] = "UnarySub" + def __init__(self, expr): self.expr = expr - self.quals = quals def getChildren(self): - children = [] - children.append(self.expr) - children.extend(flatten(self.quals)) - return tuple(children) + return self.expr, def getChildNodes(self): - nodelist = [] - nodelist.append(self.expr) - nodelist.extend(flatten_nodes(self.quals)) - return tuple(nodelist) + return self.expr, def __repr__(self): - return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) + return "UnarySub(%s)" % (repr(self.expr),) -class GenExprFor(Node): - nodes["genexprfor"] = "GenExprFor" - def __init__(self, assign, iter, ifs): - self.assign = assign - self.iter = iter - self.ifs = ifs - self.is_outmost = False +class While(Node): + nodes["while"] = "While" + def __init__(self, test, body, else_): + self.test = test + self.body = body + self.else_ = else_ def getChildren(self): children = [] - children.append(self.assign) - children.append(self.iter) - children.extend(flatten(self.ifs)) + children.append(self.test) + children.append(self.body) + children.append(self.else_) return tuple(children) def getChildNodes(self): nodelist = [] - nodelist.append(self.assign) - nodelist.append(self.iter) - nodelist.extend(flatten_nodes(self.ifs)) + nodelist.append(self.test) + nodelist.append(self.body) + if self.else_ is not None: nodelist.append(self.else_) return tuple(nodelist) def __repr__(self): - return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) + return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) -class GenExprIf(Node): - nodes["genexprif"] = "GenExprIf" - def __init__(self, test): - self.test = test +class Yield(Node): + nodes["yield"] = "Yield" + def __init__(self, value): + self.value = value def getChildren(self): - return self.test, + return self.value, def getChildNodes(self): - return self.test, + return self.value, def __repr__(self): - return "GenExprIf(%s)" % (repr(self.test),) + return "Yield(%s)" % (repr(self.value),) klasses = globals() for k in nodes.keys(): diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py index 4d5f728..e859ac5 100644 --- a/Lib/compiler/pycodegen.py +++ b/Lib/compiler/pycodegen.py @@ -366,6 +366,13 @@ class CodeGenerator: self._visitFuncOrLambda(node, isLambda=1) def _visitFuncOrLambda(self, node, isLambda=0): + if not isLambda and node.decorators: + for decorator in reversed(node.decorators.nodes): + self.visit(decorator) + ndecorators = len(node.decorators.nodes) + else: + ndecorators = 0 + gen = self.FunctionGen(node, self.scopes, isLambda, self.class_name, self.get_module()) walk(node.code, gen) @@ -382,6 +389,9 @@ class CodeGenerator: else: self.emit('LOAD_CONST', gen) self.emit('MAKE_FUNCTION', len(node.defaults)) + + for i in range(ndecorators): + self.emit('CALL_FUNCTION', 1) def visitClass(self, node): gen = self.ClassGen(node, self.scopes, diff --git a/Lib/compiler/symbols.py b/Lib/compiler/symbols.py index e1581a4..9d4605a 100644 --- a/Lib/compiler/symbols.py +++ b/Lib/compiler/symbols.py @@ -224,6 +224,8 @@ class SymbolVisitor: visitExpression = visitModule def visitFunction(self, node, parent): + if node.decorators: + self.visit(node.decorators, parent) parent.add_def(node.name) for n in node.defaults: self.visit(n, parent) diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py index aa5a28b..229657b 100644 --- a/Lib/compiler/transformer.py +++ b/Lib/compiler/transformer.py @@ -185,29 +185,81 @@ class Transformer: ### is this sufficient? return Expression(self.com_node(nodelist[0])) + def decorator_name(self, nodelist): + listlen = len(nodelist) + assert listlen >= 1 and listlen % 2 == 1 + + item = self.atom_name(nodelist) + i = 1 + while i < listlen: + assert nodelist[i][0] == token.DOT + assert nodelist[i + 1][0] == token.NAME + item = Getattr(item, nodelist[i + 1][1]) + i += 2 + + return item + + def decorator(self, nodelist): + # '@' dotted_name [ '(' [arglist] ')' ] + assert len(nodelist) in (2, 4, 5) + assert nodelist[0][0] == token.AT + + assert nodelist[1][0] == symbol.dotted_name + funcname = self.decorator_name(nodelist[1][1:]) + + if len(nodelist) > 2: + assert nodelist[2][0] == token.LPAR + expr = self.com_call_function(funcname, nodelist[3]) + else: + expr = funcname + + return expr + + def decorators(self, nodelist): + # decorators: decorator ([NEWLINE] decorator)* NEWLINE + listlen = len(nodelist) + i = 0 + items = [] + while i < listlen: + assert nodelist[i][0] == symbol.decorator + items.append(self.decorator(nodelist[i][1:])) + i += 1 + + if i < listlen and nodelist[i][0] == token.NEWLINE: + i += 1 + return Decorators(items) + def funcdef(self, nodelist): - # funcdef: 'def' NAME parameters ':' suite + # -6 -5 -4 -3 -2 -1 + # funcdef: [decorators] 'def' NAME parameters ':' suite # parameters: '(' [varargslist] ')' - lineno = nodelist[1][2] - name = nodelist[1][1] - args = nodelist[2][2] + if len(nodelist) == 6: + assert nodelist[0][0] == symbol.decorators + decorators = self.decorators(nodelist[0][1:]) + else: + assert len(nodelist) == 5 + decorators = None + + lineno = nodelist[-4][2] + name = nodelist[-4][1] + args = nodelist[-3][2] if args[0] == symbol.varargslist: names, defaults, flags = self.com_arglist(args[1:]) else: names = defaults = () flags = 0 - doc = self.get_docstring(nodelist[4]) + doc = self.get_docstring(nodelist[-1]) # code for function - code = self.com_node(nodelist[4]) + code = self.com_node(nodelist[-1]) if doc is not None: assert isinstance(code, Stmt) assert isinstance(code.nodes[0], Discard) del code.nodes[0] - n = Function(name, names, defaults, flags, doc, code) + n = Function(decorators, name, names, defaults, flags, doc, code) n.lineno = lineno return n diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py index 9e6bcb0..0812e22 100644 --- a/Lib/pyclbr.py +++ b/Lib/pyclbr.py @@ -222,7 +222,7 @@ def _readmodule(module, path, inpackage=None): else: super.append(token) inherit = names - cur_class = Class(module, class_name, inherit, file, lineno) + cur_class = Class(fullmodule, class_name, inherit, file, lineno) if not stack: dict[class_name] = cur_class stack.append((cur_class, thisindent)) diff --git a/Lib/symbol.py b/Lib/symbol.py index c839e4a..cb57208 100755 --- a/Lib/symbol.py +++ b/Lib/symbol.py @@ -13,75 +13,77 @@ single_input = 256 file_input = 257 eval_input = 258 -funcdef = 259 -parameters = 260 -varargslist = 261 -fpdef = 262 -fplist = 263 -stmt = 264 -simple_stmt = 265 -small_stmt = 266 -expr_stmt = 267 -augassign = 268 -print_stmt = 269 -del_stmt = 270 -pass_stmt = 271 -flow_stmt = 272 -break_stmt = 273 -continue_stmt = 274 -return_stmt = 275 -yield_stmt = 276 -raise_stmt = 277 -import_stmt = 278 -import_as_name = 279 -dotted_as_name = 280 -dotted_name = 281 -global_stmt = 282 -exec_stmt = 283 -assert_stmt = 284 -compound_stmt = 285 -if_stmt = 286 -while_stmt = 287 -for_stmt = 288 -try_stmt = 289 -except_clause = 290 -suite = 291 -test = 292 -and_test = 293 -not_test = 294 -comparison = 295 -comp_op = 296 -expr = 297 -xor_expr = 298 -and_expr = 299 -shift_expr = 300 -arith_expr = 301 -term = 302 -factor = 303 -power = 304 -atom = 305 -listmaker = 306 -testlist_gexp = 307 -lambdef = 308 -trailer = 309 -subscriptlist = 310 -subscript = 311 -sliceop = 312 -exprlist = 313 -testlist = 314 -testlist_safe = 315 -dictmaker = 316 -classdef = 317 -arglist = 318 -argument = 319 -list_iter = 320 -list_for = 321 -list_if = 322 -gen_iter = 323 -gen_for = 324 -gen_if = 325 -testlist1 = 326 -encoding_decl = 327 +decorator = 259 +decorators = 260 +funcdef = 261 +parameters = 262 +varargslist = 263 +fpdef = 264 +fplist = 265 +stmt = 266 +simple_stmt = 267 +small_stmt = 268 +expr_stmt = 269 +augassign = 270 +print_stmt = 271 +del_stmt = 272 +pass_stmt = 273 +flow_stmt = 274 +break_stmt = 275 +continue_stmt = 276 +return_stmt = 277 +yield_stmt = 278 +raise_stmt = 279 +import_stmt = 280 +import_as_name = 281 +dotted_as_name = 282 +dotted_name = 283 +global_stmt = 284 +exec_stmt = 285 +assert_stmt = 286 +compound_stmt = 287 +if_stmt = 288 +while_stmt = 289 +for_stmt = 290 +try_stmt = 291 +except_clause = 292 +suite = 293 +test = 294 +and_test = 295 +not_test = 296 +comparison = 297 +comp_op = 298 +expr = 299 +xor_expr = 300 +and_expr = 301 +shift_expr = 302 +arith_expr = 303 +term = 304 +factor = 305 +power = 306 +atom = 307 +listmaker = 308 +testlist_gexp = 309 +lambdef = 310 +trailer = 311 +subscriptlist = 312 +subscript = 313 +sliceop = 314 +exprlist = 315 +testlist = 316 +testlist_safe = 317 +dictmaker = 318 +classdef = 319 +arglist = 320 +argument = 321 +list_iter = 322 +list_for = 323 +list_if = 324 +gen_iter = 325 +gen_for = 326 +gen_if = 327 +testlist1 = 328 +encoding_decl = 329 #--end constants-- sym_name = {} diff --git a/Lib/test/output/test_tokenize b/Lib/test/output/test_tokenize index ea55181..b78a223 100644 --- a/Lib/test/output/test_tokenize +++ b/Lib/test/output/test_tokenize @@ -645,4 +645,15 @@ test_tokenize 174,29-174,30: OP ')' 174,30-174,31: NEWLINE '\n' 175,0-175,1: NL '\n' -176,0-176,0: ENDMARKER '' +176,0-176,1: OP '@' +176,1-176,13: NAME 'staticmethod' +176,13-176,14: NEWLINE '\n' +177,0-177,3: NAME 'def' +177,4-177,7: NAME 'foo' +177,7-177,8: OP '(' +177,8-177,9: OP ')' +177,9-177,10: OP ':' +177,11-177,15: NAME 'pass' +177,15-177,16: NEWLINE '\n' +178,0-178,1: NL '\n' +179,0-179,0: ENDMARKER '' diff --git a/Lib/test/pyclbr_input.py b/Lib/test/pyclbr_input.py new file mode 100644 index 0000000..b410fcc --- /dev/null +++ b/Lib/test/pyclbr_input.py @@ -0,0 +1,33 @@ +"""Test cases for test_pyclbr.py""" + +def f(): pass + +class Other(object): + @classmethod + def foo(c): pass + + def om(self): pass + +class B (object): + def bm(self): pass + +class C (B): + foo = Other().foo + om = Other.om + + d = 10 + + # XXX: This causes test_pyclbr.py to fail, but only because the + # introspection-based is_method() code in the test can't + # distinguish between this and a geniune method function like m(). + # The pyclbr.py module gets this right as it parses the text. + # + #f = f + + def m(self): pass + + @staticmethod + def sm(self): pass + + @classmethod + def cm(self): pass diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py new file mode 100644 index 0000000..98d5d3e --- /dev/null +++ b/Lib/test/test_decorators.py @@ -0,0 +1,194 @@ +import unittest +from test import test_support + +def funcattrs(**kwds): + def decorate(func): + func.__dict__.update(kwds) + return func + return decorate + +class MiscDecorators (object): + @staticmethod + def author(name): + def decorate(func): + func.__dict__['author'] = name + return func + return decorate + +# ----------------------------------------------- + +class DbcheckError (Exception): + def __init__(self, exprstr, func, args, kwds): + # A real version of this would set attributes here + Exception.__init__(self, "dbcheck %r failed (func=%s args=%s kwds=%s)" % + (exprstr, func, args, kwds)) + + +def dbcheck(exprstr, globals=None, locals=None): + "Decorator to implement debugging assertions" + def decorate(func): + expr = compile(exprstr, "dbcheck-%s" % func.func_name, "eval") + def check(*args, **kwds): + if not eval(expr, globals, locals): + raise DbcheckError(exprstr, func, args, kwds) + return func(*args, **kwds) + return check + return decorate + +# ----------------------------------------------- + +def countcalls(counts): + "Decorator to count calls to a function" + def decorate(func): + name = func.func_name + counts[name] = 0 + def call(*args, **kwds): + counts[name] += 1 + return func(*args, **kwds) + # XXX: Would like to say: call.func_name = func.func_name here + # to make nested decorators work in any order, but func_name + # is a readonly attribute + return call + return decorate + +# ----------------------------------------------- + +def memoize(func): + saved = {} + def call(*args): + try: + return saved[args] + except KeyError: + res = func(*args) + saved[args] = res + return res + except TypeError: + # Unhashable argument + return func(*args) + return call + +# ----------------------------------------------- + +class TestDecorators(unittest.TestCase): + + def test_single(self): + class C(object): + @staticmethod + def foo(): return 42 + self.assertEqual(C.foo(), 42) + self.assertEqual(C().foo(), 42) + + def test_dotted(self): + decorators = MiscDecorators() + @decorators.author('Cleese') + def foo(): return 42 + self.assertEqual(foo(), 42) + self.assertEqual(foo.author, 'Cleese') + + def test_argforms(self): + # A few tests of argument passing, as we use restricted form + # of expressions for decorators. + + def noteargs(*args, **kwds): + def decorate(func): + setattr(func, 'dbval', (args, kwds)) + return func + return decorate + + args = ( 'Now', 'is', 'the', 'time' ) + kwds = dict(one=1, two=2) + @noteargs(*args, **kwds) + def f1(): return 42 + self.assertEqual(f1(), 42) + self.assertEqual(f1.dbval, (args, kwds)) + + @noteargs('terry', 'gilliam', eric='idle', john='cleese') + def f2(): return 84 + self.assertEqual(f2(), 84) + self.assertEqual(f2.dbval, (('terry', 'gilliam'), + dict(eric='idle', john='cleese'))) + + @noteargs(1, 2,) + def f3(): pass + self.assertEqual(f3.dbval, ((1, 2), {})) + + def test_dbcheck(self): + @dbcheck('args[1] is not None') + def f(a, b): + return a + b + self.assertEqual(f(1, 2), 3) + self.assertRaises(DbcheckError, f, 1, None) + + def test_memoize(self): + # XXX: This doesn't work unless memoize is the last decorator - + # see the comment in countcalls. + counts = {} + @countcalls(counts) @memoize + def double(x): + return x * 2 + + self.assertEqual(counts, dict(double=0)) + + # Only the first call with a given argument bumps the call count: + # + self.assertEqual(double(2), 4) + self.assertEqual(counts['double'], 1) + self.assertEqual(double(2), 4) + self.assertEqual(counts['double'], 1) + self.assertEqual(double(3), 6) + self.assertEqual(counts['double'], 2) + + # Unhashable arguments do not get memoized: + # + self.assertEqual(double([10]), [10, 10]) + self.assertEqual(counts['double'], 3) + self.assertEqual(double([10]), [10, 10]) + self.assertEqual(counts['double'], 4) + + def test_errors(self): + # Test syntax restrictions - these are all compile-time errors: + # + for expr in [ "1+2", "x[3]", "(1, 2)" ]: + # Sanity check: is expr is a valid expression by itself? + compile(expr, "testexpr", "exec") + + codestr = "@%s\ndef f(): pass" % expr + self.assertRaises(SyntaxError, compile, codestr, "test", "exec") + + # Test runtime errors + + def unimp(func): + raise NotImplementedError + context = dict(nullval=None, unimp=unimp) + + for expr, exc in [ ("undef", NameError), + ("nullval", TypeError), + ("nullval.attr", AttributeError), + ("unimp", NotImplementedError)]: + codestr = "@%s\ndef f(): pass\nassert f() is None" % expr + code = compile(codestr, "test", "exec") + self.assertRaises(exc, eval, code, context) + + def test_double(self): + class C(object): + @funcattrs(abc=1, xyz="haha") + @funcattrs(booh=42) + def foo(self): return 42 + self.assertEqual(C().foo(), 42) + self.assertEqual(C.foo.abc, 1) + self.assertEqual(C.foo.xyz, "haha") + self.assertEqual(C.foo.booh, 42) + + def test_order(self): + class C(object): + @funcattrs(abc=1) @staticmethod + def foo(): return 42 + # This wouldn't work if staticmethod was called first + self.assertEqual(C.foo(), 42) + self.assertEqual(C().foo(), 42) + +def test_main(): + test_support.run_unittest(TestDecorators) + +if __name__=="__main__": + test_main() diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index 9652f6b..978ce57 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -15,8 +15,8 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): t = st1.totuple() try: st2 = parser.sequence2st(t) - except parser.ParserError: - self.fail("could not roundtrip %r" % s) + except parser.ParserError, why: + self.fail("could not roundtrip %r: %s" % (s, why)) self.assertEquals(t, st2.totuple(), "could not re-generate syntax tree") @@ -119,6 +119,14 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): self.check_suite("def f(a, b, foo=bar, *args, **kw): pass") self.check_suite("def f(a, b, foo=bar, **kw): pass") + self.check_suite("@staticmethod\n" + "def f(): pass") + self.check_suite("@staticmethod\n" + "@funcattrs(x, y)\n" + "def f(): pass") + self.check_suite("@funcattrs()\n" + "def f(): pass") + def test_import_from_statement(self): self.check_suite("from sys.path import *") self.check_suite("from sys.path import dirname") diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 48e8bf7..eddd593 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -8,6 +8,9 @@ from types import ClassType, FunctionType, MethodType import pyclbr from unittest import TestCase +StaticMethodType = type(staticmethod(lambda: None)) +ClassMethodType = type(classmethod(lambda c: None)) + # This next line triggers an error on old versions of pyclbr. from commands import getstatus @@ -43,11 +46,10 @@ class PyclbrTest(TestCase): print >>sys.stderr, "***",key self.failUnless(obj.has_key(key)) - def assertEquals(self, a, b, ignore=None): + def assertEqualsOrIgnored(self, a, b, ignore): ''' succeed iff a == b or a in ignore or b in ignore ''' - if (ignore == None) or (a in ignore) or (b in ignore): return - - unittest.TestCase.assertEquals(self, a, b) + if a not in ignore and b not in ignore: + self.assertEquals(a, b) def checkModule(self, moduleName, module=None, ignore=()): ''' succeed iff pyclbr.readmodule_ex(modulename) corresponds @@ -62,11 +64,22 @@ class PyclbrTest(TestCase): dict = pyclbr.readmodule_ex(moduleName) - def ismethod(obj, name): - if not isinstance(obj, MethodType): - return False - if obj.im_self is not None: - return False + def ismethod(oclass, obj, name): + classdict = oclass.__dict__ + if isinstance(obj, FunctionType): + if not isinstance(classdict[name], StaticMethodType): + return False + else: + if not isinstance(obj, MethodType): + return False + if obj.im_self is not None: + if (not isinstance(classdict[name], ClassMethodType) or + obj.im_self is not oclass): + return False + else: + if not isinstance(classdict[name], FunctionType): + return False + objname = obj.__name__ if objname.startswith("__") and not objname.endswith("__"): objname = "_%s%s" % (obj.im_class.__name__, objname) @@ -81,7 +94,7 @@ class PyclbrTest(TestCase): if isinstance(value, pyclbr.Function): self.assertEquals(type(py_item), FunctionType) else: - self.assertEquals(type(py_item), ClassType) + self.failUnless(isinstance(py_item, (ClassType, type))) real_bases = [base.__name__ for base in py_item.__bases__] pyclbr_bases = [ getattr(base, 'name', base) for base in value.super ] @@ -94,7 +107,7 @@ class PyclbrTest(TestCase): actualMethods = [] for m in py_item.__dict__.keys(): - if ismethod(getattr(py_item, m), m): + if ismethod(py_item, getattr(py_item, m), m): actualMethods.append(m) foundMethods = [] for m in value.methods.keys(): @@ -107,7 +120,8 @@ class PyclbrTest(TestCase): self.assertListEq(foundMethods, actualMethods, ignore) self.assertEquals(py_item.__module__, value.module) - self.assertEquals(py_item.__name__, value.name, ignore) + self.assertEqualsOrIgnored(py_item.__name__, value.name, + ignore) # can't check file or lineno except: print >>sys.stderr, "class=%s" % py_item @@ -132,6 +146,12 @@ class PyclbrTest(TestCase): self.checkModule('rfc822') self.checkModule('difflib') + def test_decorators(self): + # XXX: See comment in pyclbr_input.py for a test that would fail + # if it were not commented out. + # + self.checkModule('test.pyclbr_input') + def test_others(self): cm = self.checkModule diff --git a/Lib/test/tokenize_tests.txt b/Lib/test/tokenize_tests.txt index e990a36..4ef3bf1 100644 --- a/Lib/test/tokenize_tests.txt +++ b/Lib/test/tokenize_tests.txt @@ -173,3 +173,6 @@ x = -1*1/1 + 1*1 - ---1*1 import sys, time x = sys.modules['time'].time() +@staticmethod +def foo(): pass + diff --git a/Lib/token.py b/Lib/token.py index f75412c..c4db6c5 100755 --- a/Lib/token.py +++ b/Lib/token.py @@ -60,9 +60,10 @@ RIGHTSHIFTEQUAL = 46 DOUBLESTAREQUAL = 47 DOUBLESLASH = 48 DOUBLESLASHEQUAL = 49 -OP = 50 -ERRORTOKEN = 51 -N_TOKENS = 52 +AT = 50 +OP = 51 +ERRORTOKEN = 52 +N_TOKENS = 53 NT_OFFSET = 256 #--end constants-- diff --git a/Lib/tokenize.py b/Lib/tokenize.py index 7e6fa12..9087e84 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -83,7 +83,7 @@ Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", r"~") Bracket = '[][(){}]' -Special = group(r'\r?\n', r'[:;.,`]') +Special = group(r'\r?\n', r'[:;.,`@]') Funny = group(Operator, Bracket, Special) PlainToken = group(Number, Funny, String, Name) |