[pypy-commit] pypy split-ast-classes: Progress: Implement all from_object() methods

amauryfa noreply at buildbot.pypy.org
Wed Jun 26 23:22:10 CEST 2013


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: split-ast-classes
Changeset: r65018:0354de7ac1fb
Date: 2013-06-24 22:23 +0200
http://bitbucket.org/pypy/pypy/changeset/0354de7ac1fb/

Log:	Progress: Implement all from_object() methods

diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -1,12 +1,27 @@
 # Generated by tools/asdl_py.py
-from pypy.interpreter.error import OperationError
-from rpython.tool.pairtype import extendabletype
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter import typedef
 from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.error import OperationError, operationerrfmt
+from rpython.tool.pairtype import extendabletype
 from rpython.tool.sourcetools import func_with_new_name
 
 
+def check_string(space, w_obj):
+    if not (space.isinstance_w(w_obj, space.w_str) or
+            space.isinstance_w(w_obj, space.w_unicode)):
+        raise OperationError(space.w_TypeError, space.wrap(
+                'AST string must be of type str or unicode'))
+    return w_obj
+
+def get_field(space, w_node, name, optional):
+    w_obj = w_node.getdictvalue(space, name)
+    if w_obj is None and not optional:
+        raise operationerrfmt(space.w_TypeError,
+                "required field \"%s\" missing from %T", name, w_node)
+    return w_obj
+
+
 class AST(object):
     __metaclass__ = extendabletype
 
@@ -34,13 +49,6 @@
 class W_AST(W_Root):
     w_dict = None
 
-    def obj2mod(self, space):
-        if space.isinstance_w(self, get(space).w_Module):
-            return Module.from_object(space, self)
-        else:
-            raise OperationError(space.w_TypeError, space.wrap(
-                    "Expected mod node"))
-
     def getdict(self, space):
         if self.w_dict is None:
             self.w_dict = space.newdict(instance=True)
@@ -120,7 +128,18 @@
     return space.fromcache(State)
 
 class mod(AST):
-    pass
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_Module):
+            return Module.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Interactive):
+            return Interactive.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Expression):
+            return Expression.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Suite):
+            return Suite.from_object(space, w_node)
+        raise operationerrfmt(space.w_TypeError,
+                "Expected mod node, got %T", w_node)
 State.ast_type('mod', 'AST')
 
 class Module(mod):
@@ -148,7 +167,9 @@
 
     @staticmethod
     def from_object(space, w_node):
-        body = space.getattr(w_node, space.wrap('body'))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
         return Module(body)
 
 State.ast_type('Module', 'mod')
@@ -179,7 +200,9 @@
 
     @staticmethod
     def from_object(space, w_node):
-        body = space.getattr(w_node, space.wrap('body'))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
         return Interactive(body)
 
 State.ast_type('Interactive', 'mod')
@@ -205,7 +228,7 @@
 
     @staticmethod
     def from_object(space, w_node):
-        body = space.getattr(w_node, space.wrap('body'))
+        body = expr.from_object(space, space.getattr(w_node, space.wrap('body')))
         return Expression(body)
 
 State.ast_type('Expression', 'mod')
@@ -236,7 +259,9 @@
 
     @staticmethod
     def from_object(space, w_node):
-        body = space.getattr(w_node, space.wrap('body'))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
         return Suite(body)
 
 State.ast_type('Suite', 'mod')
@@ -247,6 +272,57 @@
     def __init__(self, lineno, col_offset):
         self.lineno = lineno
         self.col_offset = col_offset
+
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_FunctionDef):
+            return FunctionDef.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_ClassDef):
+            return ClassDef.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Return):
+            return Return.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Delete):
+            return Delete.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Assign):
+            return Assign.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_AugAssign):
+            return AugAssign.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Print):
+            return Print.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_For):
+            return For.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_While):
+            return While.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_If):
+            return If.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_With):
+            return With.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Raise):
+            return Raise.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_TryExcept):
+            return TryExcept.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_TryFinally):
+            return TryFinally.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Assert):
+            return Assert.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Import):
+            return Import.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_ImportFrom):
+            return ImportFrom.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Exec):
+            return Exec.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Global):
+            return Global.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Expr):
+            return Expr.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Pass):
+            return Pass.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Break):
+            return Break.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Continue):
+            return Continue.from_object(space, w_node)
+        raise operationerrfmt(space.w_TypeError,
+                "Expected stmt node, got %T", w_node)
 State.ast_type('stmt', 'AST')
 
 class FunctionDef(stmt):
@@ -287,15 +363,25 @@
             decorator_list_w = [node.to_object(space) for node in self.decorator_list] # expr
         w_decorator_list = space.newlist(decorator_list_w)
         space.setattr(w_node, space.wrap('decorator_list'), w_decorator_list)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        name = space.getattr(w_node, space.wrap('name'))
-        args = space.getattr(w_node, space.wrap('args'))
-        body = space.getattr(w_node, space.wrap('body'))
-        decorator_list = space.getattr(w_node, space.wrap('decorator_list'))
-        return FunctionDef(name, args, body, decorator_list)
+        name = space.str_w(space.getattr(w_node, space.wrap('name')))
+        args = arguments.from_object(space, space.getattr(w_node, space.wrap('args')))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        decorator_list_w = space.unpackiterable(
+                get_field(space, w_node, 'decorator_list', False))
+        decorator_list = [expr.from_object(space, w_item) for w_item in decorator_list_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return FunctionDef(name, args, body, decorator_list, lineno, col_offset)
 
 State.ast_type('FunctionDef', 'stmt')
 
@@ -343,15 +429,27 @@
             decorator_list_w = [node.to_object(space) for node in self.decorator_list] # expr
         w_decorator_list = space.newlist(decorator_list_w)
         space.setattr(w_node, space.wrap('decorator_list'), w_decorator_list)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        name = space.getattr(w_node, space.wrap('name'))
-        bases = space.getattr(w_node, space.wrap('bases'))
-        body = space.getattr(w_node, space.wrap('body'))
-        decorator_list = space.getattr(w_node, space.wrap('decorator_list'))
-        return ClassDef(name, bases, body, decorator_list)
+        name = space.str_w(space.getattr(w_node, space.wrap('name')))
+        bases_w = space.unpackiterable(
+                get_field(space, w_node, 'bases', False))
+        bases = [expr.from_object(space, w_item) for w_item in bases_w]
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        decorator_list_w = space.unpackiterable(
+                get_field(space, w_node, 'decorator_list', False))
+        decorator_list = [expr.from_object(space, w_item) for w_item in decorator_list_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return ClassDef(name, bases, body, decorator_list, lineno, col_offset)
 
 State.ast_type('ClassDef', 'stmt')
 
@@ -374,12 +472,18 @@
         w_node = space.call_function(get(space).w_Return)
         w_value = self.value.to_object(space)  # expr
         space.setattr(w_node, space.wrap('value'), w_value)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        value = space.getattr(w_node, space.wrap('value'))
-        return Return(value)
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Return(value, lineno, col_offset)
 
 State.ast_type('Return', 'stmt')
 
@@ -406,12 +510,20 @@
             targets_w = [node.to_object(space) for node in self.targets] # expr
         w_targets = space.newlist(targets_w)
         space.setattr(w_node, space.wrap('targets'), w_targets)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        targets = space.getattr(w_node, space.wrap('targets'))
-        return Delete(targets)
+        targets_w = space.unpackiterable(
+                get_field(space, w_node, 'targets', False))
+        targets = [expr.from_object(space, w_item) for w_item in targets_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Delete(targets, lineno, col_offset)
 
 State.ast_type('Delete', 'stmt')
 
@@ -442,13 +554,21 @@
         space.setattr(w_node, space.wrap('targets'), w_targets)
         w_value = self.value.to_object(space)  # expr
         space.setattr(w_node, space.wrap('value'), w_value)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        targets = space.getattr(w_node, space.wrap('targets'))
-        value = space.getattr(w_node, space.wrap('value'))
-        return Assign(targets, value)
+        targets_w = space.unpackiterable(
+                get_field(space, w_node, 'targets', False))
+        targets = [expr.from_object(space, w_item) for w_item in targets_w]
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Assign(targets, value, lineno, col_offset)
 
 State.ast_type('Assign', 'stmt')
 
@@ -477,14 +597,20 @@
         space.setattr(w_node, space.wrap('op'), w_op)
         w_value = self.value.to_object(space)  # expr
         space.setattr(w_node, space.wrap('value'), w_value)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        target = space.getattr(w_node, space.wrap('target'))
-        op = space.getattr(w_node, space.wrap('op'))
-        value = space.getattr(w_node, space.wrap('value'))
-        return AugAssign(target, op, value)
+        target = expr.from_object(space, space.getattr(w_node, space.wrap('target')))
+        op = operator.from_object(space, space.getattr(w_node, space.wrap('op')))
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return AugAssign(target, op, value, lineno, col_offset)
 
 State.ast_type('AugAssign', 'stmt')
 
@@ -519,14 +645,22 @@
         space.setattr(w_node, space.wrap('values'), w_values)
         w_nl = self.nl.to_object(space)  # bool
         space.setattr(w_node, space.wrap('nl'), w_nl)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        dest = space.getattr(w_node, space.wrap('dest'))
-        values = space.getattr(w_node, space.wrap('values'))
-        nl = space.getattr(w_node, space.wrap('nl'))
-        return Print(dest, values, nl)
+        dest = expr.from_object(space, space.getattr(w_node, space.wrap('dest')))
+        values_w = space.unpackiterable(
+                get_field(space, w_node, 'values', False))
+        values = [expr.from_object(space, w_item) for w_item in values_w]
+        nl = bool.from_object(space, space.getattr(w_node, space.wrap('nl')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Print(dest, values, nl, lineno, col_offset)
 
 State.ast_type('Print', 'stmt')
 
@@ -570,15 +704,25 @@
             orelse_w = [node.to_object(space) for node in self.orelse] # stmt
         w_orelse = space.newlist(orelse_w)
         space.setattr(w_node, space.wrap('orelse'), w_orelse)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        target = space.getattr(w_node, space.wrap('target'))
-        iter = space.getattr(w_node, space.wrap('iter'))
-        body = space.getattr(w_node, space.wrap('body'))
-        orelse = space.getattr(w_node, space.wrap('orelse'))
-        return For(target, iter, body, orelse)
+        target = expr.from_object(space, space.getattr(w_node, space.wrap('target')))
+        iter = expr.from_object(space, space.getattr(w_node, space.wrap('iter')))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        orelse_w = space.unpackiterable(
+                get_field(space, w_node, 'orelse', False))
+        orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return For(target, iter, body, orelse, lineno, col_offset)
 
 State.ast_type('For', 'stmt')
 
@@ -618,14 +762,24 @@
             orelse_w = [node.to_object(space) for node in self.orelse] # stmt
         w_orelse = space.newlist(orelse_w)
         space.setattr(w_node, space.wrap('orelse'), w_orelse)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        test = space.getattr(w_node, space.wrap('test'))
-        body = space.getattr(w_node, space.wrap('body'))
-        orelse = space.getattr(w_node, space.wrap('orelse'))
-        return While(test, body, orelse)
+        test = expr.from_object(space, space.getattr(w_node, space.wrap('test')))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        orelse_w = space.unpackiterable(
+                get_field(space, w_node, 'orelse', False))
+        orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return While(test, body, orelse, lineno, col_offset)
 
 State.ast_type('While', 'stmt')
 
@@ -665,14 +819,24 @@
             orelse_w = [node.to_object(space) for node in self.orelse] # stmt
         w_orelse = space.newlist(orelse_w)
         space.setattr(w_node, space.wrap('orelse'), w_orelse)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        test = space.getattr(w_node, space.wrap('test'))
-        body = space.getattr(w_node, space.wrap('body'))
-        orelse = space.getattr(w_node, space.wrap('orelse'))
-        return If(test, body, orelse)
+        test = expr.from_object(space, space.getattr(w_node, space.wrap('test')))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        orelse_w = space.unpackiterable(
+                get_field(space, w_node, 'orelse', False))
+        orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return If(test, body, orelse, lineno, col_offset)
 
 State.ast_type('If', 'stmt')
 
@@ -708,14 +872,22 @@
             body_w = [node.to_object(space) for node in self.body] # stmt
         w_body = space.newlist(body_w)
         space.setattr(w_node, space.wrap('body'), w_body)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        context_expr = space.getattr(w_node, space.wrap('context_expr'))
-        optional_vars = space.getattr(w_node, space.wrap('optional_vars'))
-        body = space.getattr(w_node, space.wrap('body'))
-        return With(context_expr, optional_vars, body)
+        context_expr = expr.from_object(space, space.getattr(w_node, space.wrap('context_expr')))
+        optional_vars = expr.from_object(space, space.getattr(w_node, space.wrap('optional_vars')))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return With(context_expr, optional_vars, body, lineno, col_offset)
 
 State.ast_type('With', 'stmt')
 
@@ -748,14 +920,20 @@
         space.setattr(w_node, space.wrap('inst'), w_inst)
         w_tback = self.tback.to_object(space)  # expr
         space.setattr(w_node, space.wrap('tback'), w_tback)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        type = space.getattr(w_node, space.wrap('type'))
-        inst = space.getattr(w_node, space.wrap('inst'))
-        tback = space.getattr(w_node, space.wrap('tback'))
-        return Raise(type, inst, tback)
+        type = expr.from_object(space, space.getattr(w_node, space.wrap('type')))
+        inst = expr.from_object(space, space.getattr(w_node, space.wrap('inst')))
+        tback = expr.from_object(space, space.getattr(w_node, space.wrap('tback')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Raise(type, inst, tback, lineno, col_offset)
 
 State.ast_type('Raise', 'stmt')
 
@@ -800,14 +978,26 @@
             orelse_w = [node.to_object(space) for node in self.orelse] # stmt
         w_orelse = space.newlist(orelse_w)
         space.setattr(w_node, space.wrap('orelse'), w_orelse)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        body = space.getattr(w_node, space.wrap('body'))
-        handlers = space.getattr(w_node, space.wrap('handlers'))
-        orelse = space.getattr(w_node, space.wrap('orelse'))
-        return TryExcept(body, handlers, orelse)
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        handlers_w = space.unpackiterable(
+                get_field(space, w_node, 'handlers', False))
+        handlers = [excepthandler.from_object(space, w_item) for w_item in handlers_w]
+        orelse_w = space.unpackiterable(
+                get_field(space, w_node, 'orelse', False))
+        orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return TryExcept(body, handlers, orelse, lineno, col_offset)
 
 State.ast_type('TryExcept', 'stmt')
 
@@ -843,13 +1033,23 @@
             finalbody_w = [node.to_object(space) for node in self.finalbody] # stmt
         w_finalbody = space.newlist(finalbody_w)
         space.setattr(w_node, space.wrap('finalbody'), w_finalbody)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        body = space.getattr(w_node, space.wrap('body'))
-        finalbody = space.getattr(w_node, space.wrap('finalbody'))
-        return TryFinally(body, finalbody)
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        finalbody_w = space.unpackiterable(
+                get_field(space, w_node, 'finalbody', False))
+        finalbody = [stmt.from_object(space, w_item) for w_item in finalbody_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return TryFinally(body, finalbody, lineno, col_offset)
 
 State.ast_type('TryFinally', 'stmt')
 
@@ -876,13 +1076,19 @@
         space.setattr(w_node, space.wrap('test'), w_test)
         w_msg = self.msg.to_object(space)  # expr
         space.setattr(w_node, space.wrap('msg'), w_msg)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        test = space.getattr(w_node, space.wrap('test'))
-        msg = space.getattr(w_node, space.wrap('msg'))
-        return Assert(test, msg)
+        test = expr.from_object(space, space.getattr(w_node, space.wrap('test')))
+        msg = expr.from_object(space, space.getattr(w_node, space.wrap('msg')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Assert(test, msg, lineno, col_offset)
 
 State.ast_type('Assert', 'stmt')
 
@@ -909,12 +1115,20 @@
             names_w = [node.to_object(space) for node in self.names] # alias
         w_names = space.newlist(names_w)
         space.setattr(w_node, space.wrap('names'), w_names)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        names = space.getattr(w_node, space.wrap('names'))
-        return Import(names)
+        names_w = space.unpackiterable(
+                get_field(space, w_node, 'names', False))
+        names = [alias.from_object(space, w_item) for w_item in names_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Import(names, lineno, col_offset)
 
 State.ast_type('Import', 'stmt')
 
@@ -947,14 +1161,22 @@
         space.setattr(w_node, space.wrap('names'), w_names)
         w_level = space.wrap(self.level)  # int
         space.setattr(w_node, space.wrap('level'), w_level)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        module = space.getattr(w_node, space.wrap('module'))
-        names = space.getattr(w_node, space.wrap('names'))
-        level = space.getattr(w_node, space.wrap('level'))
-        return ImportFrom(module, names, level)
+        module = space.str_w(space.getattr(w_node, space.wrap('module')))
+        names_w = space.unpackiterable(
+                get_field(space, w_node, 'names', False))
+        names = [alias.from_object(space, w_item) for w_item in names_w]
+        level = space.int_w(space.getattr(w_node, space.wrap('level')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return ImportFrom(module, names, level, lineno, col_offset)
 
 State.ast_type('ImportFrom', 'stmt')
 
@@ -986,14 +1208,20 @@
         space.setattr(w_node, space.wrap('globals'), w_globals)
         w_locals = self.locals.to_object(space)  # expr
         space.setattr(w_node, space.wrap('locals'), w_locals)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        body = space.getattr(w_node, space.wrap('body'))
-        globals = space.getattr(w_node, space.wrap('globals'))
-        locals = space.getattr(w_node, space.wrap('locals'))
-        return Exec(body, globals, locals)
+        body = expr.from_object(space, space.getattr(w_node, space.wrap('body')))
+        globals = expr.from_object(space, space.getattr(w_node, space.wrap('globals')))
+        locals = expr.from_object(space, space.getattr(w_node, space.wrap('locals')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Exec(body, globals, locals, lineno, col_offset)
 
 State.ast_type('Exec', 'stmt')
 
@@ -1018,12 +1246,20 @@
             names_w = [space.wrap(node) for node in self.names] # identifier
         w_names = space.newlist(names_w)
         space.setattr(w_node, space.wrap('names'), w_names)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        names = space.getattr(w_node, space.wrap('names'))
-        return Global(names)
+        names_w = space.unpackiterable(
+                get_field(space, w_node, 'names', False))
+        names = [space.str_w(w_item) for w_item in names_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Global(names, lineno, col_offset)
 
 State.ast_type('Global', 'stmt')
 
@@ -1045,12 +1281,18 @@
         w_node = space.call_function(get(space).w_Expr)
         w_value = self.value.to_object(space)  # expr
         space.setattr(w_node, space.wrap('value'), w_value)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        value = space.getattr(w_node, space.wrap('value'))
-        return Expr(value)
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Expr(value, lineno, col_offset)
 
 State.ast_type('Expr', 'stmt')
 
@@ -1068,11 +1310,17 @@
 
     def to_object(self, space):
         w_node = space.call_function(get(space).w_Pass)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        return Pass()
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Pass(lineno, col_offset)
 
 State.ast_type('Pass', 'stmt')
 
@@ -1090,11 +1338,17 @@
 
     def to_object(self, space):
         w_node = space.call_function(get(space).w_Break)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        return Break()
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Break(lineno, col_offset)
 
 State.ast_type('Break', 'stmt')
 
@@ -1112,11 +1366,17 @@
 
     def to_object(self, space):
         w_node = space.call_function(get(space).w_Continue)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        return Continue()
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Continue(lineno, col_offset)
 
 State.ast_type('Continue', 'stmt')
 
@@ -1126,6 +1386,57 @@
     def __init__(self, lineno, col_offset):
         self.lineno = lineno
         self.col_offset = col_offset
+
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_BoolOp):
+            return BoolOp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_BinOp):
+            return BinOp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_UnaryOp):
+            return UnaryOp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Lambda):
+            return Lambda.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_IfExp):
+            return IfExp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Dict):
+            return Dict.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Set):
+            return Set.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_ListComp):
+            return ListComp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_SetComp):
+            return SetComp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_DictComp):
+            return DictComp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_GeneratorExp):
+            return GeneratorExp.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Yield):
+            return Yield.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Compare):
+            return Compare.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Call):
+            return Call.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Repr):
+            return Repr.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Num):
+            return Num.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Str):
+            return Str.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Attribute):
+            return Attribute.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Subscript):
+            return Subscript.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Name):
+            return Name.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_List):
+            return List.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Tuple):
+            return Tuple.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Const):
+            return Const.from_object(space, w_node)
+        raise operationerrfmt(space.w_TypeError,
+                "Expected expr node, got %T", w_node)
 State.ast_type('expr', 'AST')
 
 class BoolOp(expr):
@@ -1153,13 +1464,21 @@
             values_w = [node.to_object(space) for node in self.values] # expr
         w_values = space.newlist(values_w)
         space.setattr(w_node, space.wrap('values'), w_values)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        op = space.getattr(w_node, space.wrap('op'))
-        values = space.getattr(w_node, space.wrap('values'))
-        return BoolOp(op, values)
+        op = boolop.from_object(space, space.getattr(w_node, space.wrap('op')))
+        values_w = space.unpackiterable(
+                get_field(space, w_node, 'values', False))
+        values = [expr.from_object(space, w_item) for w_item in values_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return BoolOp(op, values, lineno, col_offset)
 
 State.ast_type('BoolOp', 'expr')
 
@@ -1188,14 +1507,20 @@
         space.setattr(w_node, space.wrap('op'), w_op)
         w_right = self.right.to_object(space)  # expr
         space.setattr(w_node, space.wrap('right'), w_right)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        left = space.getattr(w_node, space.wrap('left'))
-        op = space.getattr(w_node, space.wrap('op'))
-        right = space.getattr(w_node, space.wrap('right'))
-        return BinOp(left, op, right)
+        left = expr.from_object(space, space.getattr(w_node, space.wrap('left')))
+        op = operator.from_object(space, space.getattr(w_node, space.wrap('op')))
+        right = expr.from_object(space, space.getattr(w_node, space.wrap('right')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return BinOp(left, op, right, lineno, col_offset)
 
 State.ast_type('BinOp', 'expr')
 
@@ -1220,13 +1545,19 @@
         space.setattr(w_node, space.wrap('op'), w_op)
         w_operand = self.operand.to_object(space)  # expr
         space.setattr(w_node, space.wrap('operand'), w_operand)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        op = space.getattr(w_node, space.wrap('op'))
-        operand = space.getattr(w_node, space.wrap('operand'))
-        return UnaryOp(op, operand)
+        op = unaryop.from_object(space, space.getattr(w_node, space.wrap('op')))
+        operand = expr.from_object(space, space.getattr(w_node, space.wrap('operand')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return UnaryOp(op, operand, lineno, col_offset)
 
 State.ast_type('UnaryOp', 'expr')
 
@@ -1252,13 +1583,19 @@
         space.setattr(w_node, space.wrap('args'), w_args)
         w_body = self.body.to_object(space)  # expr
         space.setattr(w_node, space.wrap('body'), w_body)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        args = space.getattr(w_node, space.wrap('args'))
-        body = space.getattr(w_node, space.wrap('body'))
-        return Lambda(args, body)
+        args = arguments.from_object(space, space.getattr(w_node, space.wrap('args')))
+        body = expr.from_object(space, space.getattr(w_node, space.wrap('body')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Lambda(args, body, lineno, col_offset)
 
 State.ast_type('Lambda', 'expr')
 
@@ -1288,14 +1625,20 @@
         space.setattr(w_node, space.wrap('body'), w_body)
         w_orelse = self.orelse.to_object(space)  # expr
         space.setattr(w_node, space.wrap('orelse'), w_orelse)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        test = space.getattr(w_node, space.wrap('test'))
-        body = space.getattr(w_node, space.wrap('body'))
-        orelse = space.getattr(w_node, space.wrap('orelse'))
-        return IfExp(test, body, orelse)
+        test = expr.from_object(space, space.getattr(w_node, space.wrap('test')))
+        body = expr.from_object(space, space.getattr(w_node, space.wrap('body')))
+        orelse = expr.from_object(space, space.getattr(w_node, space.wrap('orelse')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return IfExp(test, body, orelse, lineno, col_offset)
 
 State.ast_type('IfExp', 'expr')
 
@@ -1331,13 +1674,23 @@
             values_w = [node.to_object(space) for node in self.values] # expr
         w_values = space.newlist(values_w)
         space.setattr(w_node, space.wrap('values'), w_values)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        keys = space.getattr(w_node, space.wrap('keys'))
-        values = space.getattr(w_node, space.wrap('values'))
-        return Dict(keys, values)
+        keys_w = space.unpackiterable(
+                get_field(space, w_node, 'keys', False))
+        keys = [expr.from_object(space, w_item) for w_item in keys_w]
+        values_w = space.unpackiterable(
+                get_field(space, w_node, 'values', False))
+        values = [expr.from_object(space, w_item) for w_item in values_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Dict(keys, values, lineno, col_offset)
 
 State.ast_type('Dict', 'expr')
 
@@ -1364,12 +1717,20 @@
             elts_w = [node.to_object(space) for node in self.elts] # expr
         w_elts = space.newlist(elts_w)
         space.setattr(w_node, space.wrap('elts'), w_elts)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        elts = space.getattr(w_node, space.wrap('elts'))
-        return Set(elts)
+        elts_w = space.unpackiterable(
+                get_field(space, w_node, 'elts', False))
+        elts = [expr.from_object(space, w_item) for w_item in elts_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Set(elts, lineno, col_offset)
 
 State.ast_type('Set', 'expr')
 
@@ -1400,13 +1761,21 @@
             generators_w = [node.to_object(space) for node in self.generators] # comprehension
         w_generators = space.newlist(generators_w)
         space.setattr(w_node, space.wrap('generators'), w_generators)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        elt = space.getattr(w_node, space.wrap('elt'))
-        generators = space.getattr(w_node, space.wrap('generators'))
-        return ListComp(elt, generators)
+        elt = expr.from_object(space, space.getattr(w_node, space.wrap('elt')))
+        generators_w = space.unpackiterable(
+                get_field(space, w_node, 'generators', False))
+        generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return ListComp(elt, generators, lineno, col_offset)
 
 State.ast_type('ListComp', 'expr')
 
@@ -1437,13 +1806,21 @@
             generators_w = [node.to_object(space) for node in self.generators] # comprehension
         w_generators = space.newlist(generators_w)
         space.setattr(w_node, space.wrap('generators'), w_generators)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        elt = space.getattr(w_node, space.wrap('elt'))
-        generators = space.getattr(w_node, space.wrap('generators'))
-        return SetComp(elt, generators)
+        elt = expr.from_object(space, space.getattr(w_node, space.wrap('elt')))
+        generators_w = space.unpackiterable(
+                get_field(space, w_node, 'generators', False))
+        generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return SetComp(elt, generators, lineno, col_offset)
 
 State.ast_type('SetComp', 'expr')
 
@@ -1478,14 +1855,22 @@
             generators_w = [node.to_object(space) for node in self.generators] # comprehension
         w_generators = space.newlist(generators_w)
         space.setattr(w_node, space.wrap('generators'), w_generators)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        key = space.getattr(w_node, space.wrap('key'))
-        value = space.getattr(w_node, space.wrap('value'))
-        generators = space.getattr(w_node, space.wrap('generators'))
-        return DictComp(key, value, generators)
+        key = expr.from_object(space, space.getattr(w_node, space.wrap('key')))
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        generators_w = space.unpackiterable(
+                get_field(space, w_node, 'generators', False))
+        generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return DictComp(key, value, generators, lineno, col_offset)
 
 State.ast_type('DictComp', 'expr')
 
@@ -1516,13 +1901,21 @@
             generators_w = [node.to_object(space) for node in self.generators] # comprehension
         w_generators = space.newlist(generators_w)
         space.setattr(w_node, space.wrap('generators'), w_generators)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        elt = space.getattr(w_node, space.wrap('elt'))
-        generators = space.getattr(w_node, space.wrap('generators'))
-        return GeneratorExp(elt, generators)
+        elt = expr.from_object(space, space.getattr(w_node, space.wrap('elt')))
+        generators_w = space.unpackiterable(
+                get_field(space, w_node, 'generators', False))
+        generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return GeneratorExp(elt, generators, lineno, col_offset)
 
 State.ast_type('GeneratorExp', 'expr')
 
@@ -1545,12 +1938,18 @@
         w_node = space.call_function(get(space).w_Yield)
         w_value = self.value.to_object(space)  # expr
         space.setattr(w_node, space.wrap('value'), w_value)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        value = space.getattr(w_node, space.wrap('value'))
-        return Yield(value)
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Yield(value, lineno, col_offset)
 
 State.ast_type('Yield', 'expr')
 
@@ -1588,14 +1987,24 @@
             comparators_w = [node.to_object(space) for node in self.comparators] # expr
         w_comparators = space.newlist(comparators_w)
         space.setattr(w_node, space.wrap('comparators'), w_comparators)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        left = space.getattr(w_node, space.wrap('left'))
-        ops = space.getattr(w_node, space.wrap('ops'))
-        comparators = space.getattr(w_node, space.wrap('comparators'))
-        return Compare(left, ops, comparators)
+        left = expr.from_object(space, space.getattr(w_node, space.wrap('left')))
+        ops_w = space.unpackiterable(
+                get_field(space, w_node, 'ops', False))
+        ops = [cmpop.from_object(space, w_item) for w_item in ops_w]
+        comparators_w = space.unpackiterable(
+                get_field(space, w_node, 'comparators', False))
+        comparators = [expr.from_object(space, w_item) for w_item in comparators_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Compare(left, ops, comparators, lineno, col_offset)
 
 State.ast_type('Compare', 'expr')
 
@@ -1645,16 +2054,26 @@
         space.setattr(w_node, space.wrap('starargs'), w_starargs)
         w_kwargs = self.kwargs.to_object(space)  # expr
         space.setattr(w_node, space.wrap('kwargs'), w_kwargs)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        func = space.getattr(w_node, space.wrap('func'))
-        args = space.getattr(w_node, space.wrap('args'))
-        keywords = space.getattr(w_node, space.wrap('keywords'))
-        starargs = space.getattr(w_node, space.wrap('starargs'))
-        kwargs = space.getattr(w_node, space.wrap('kwargs'))
-        return Call(func, args, keywords, starargs, kwargs)
+        func = expr.from_object(space, space.getattr(w_node, space.wrap('func')))
+        args_w = space.unpackiterable(
+                get_field(space, w_node, 'args', False))
+        args = [expr.from_object(space, w_item) for w_item in args_w]
+        keywords_w = space.unpackiterable(
+                get_field(space, w_node, 'keywords', False))
+        keywords = [keyword.from_object(space, w_item) for w_item in keywords_w]
+        starargs = expr.from_object(space, space.getattr(w_node, space.wrap('starargs')))
+        kwargs = expr.from_object(space, space.getattr(w_node, space.wrap('kwargs')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Call(func, args, keywords, starargs, kwargs, lineno, col_offset)
 
 State.ast_type('Call', 'expr')
 
@@ -1676,12 +2095,18 @@
         w_node = space.call_function(get(space).w_Repr)
         w_value = self.value.to_object(space)  # expr
         space.setattr(w_node, space.wrap('value'), w_value)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        value = space.getattr(w_node, space.wrap('value'))
-        return Repr(value)
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Repr(value, lineno, col_offset)
 
 State.ast_type('Repr', 'expr')
 
@@ -1702,12 +2127,18 @@
         w_node = space.call_function(get(space).w_Num)
         w_n = self.n  # object
         space.setattr(w_node, space.wrap('n'), w_n)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
         n = space.getattr(w_node, space.wrap('n'))
-        return Num(n)
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Num(n, lineno, col_offset)
 
 State.ast_type('Num', 'expr')
 
@@ -1728,12 +2159,18 @@
         w_node = space.call_function(get(space).w_Str)
         w_s = self.s  # string
         space.setattr(w_node, space.wrap('s'), w_s)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        s = space.getattr(w_node, space.wrap('s'))
-        return Str(s)
+        s = check_string(space, space.getattr(w_node, space.wrap('s')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Str(s, lineno, col_offset)
 
 State.ast_type('Str', 'expr')
 
@@ -1761,14 +2198,20 @@
         space.setattr(w_node, space.wrap('attr'), w_attr)
         w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
         space.setattr(w_node, space.wrap('ctx'), w_ctx)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        value = space.getattr(w_node, space.wrap('value'))
-        attr = space.getattr(w_node, space.wrap('attr'))
-        ctx = space.getattr(w_node, space.wrap('ctx'))
-        return Attribute(value, attr, ctx)
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        attr = space.str_w(space.getattr(w_node, space.wrap('attr')))
+        ctx = expr_context.from_object(space, space.getattr(w_node, space.wrap('ctx')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Attribute(value, attr, ctx, lineno, col_offset)
 
 State.ast_type('Attribute', 'expr')
 
@@ -1797,14 +2240,20 @@
         space.setattr(w_node, space.wrap('slice'), w_slice)
         w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
         space.setattr(w_node, space.wrap('ctx'), w_ctx)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        value = space.getattr(w_node, space.wrap('value'))
-        slice = space.getattr(w_node, space.wrap('slice'))
-        ctx = space.getattr(w_node, space.wrap('ctx'))
-        return Subscript(value, slice, ctx)
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
+        slice = slice.from_object(space, space.getattr(w_node, space.wrap('slice')))
+        ctx = expr_context.from_object(space, space.getattr(w_node, space.wrap('ctx')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Subscript(value, slice, ctx, lineno, col_offset)
 
 State.ast_type('Subscript', 'expr')
 
@@ -1828,13 +2277,19 @@
         space.setattr(w_node, space.wrap('id'), w_id)
         w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
         space.setattr(w_node, space.wrap('ctx'), w_ctx)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        id = space.getattr(w_node, space.wrap('id'))
-        ctx = space.getattr(w_node, space.wrap('ctx'))
-        return Name(id, ctx)
+        id = space.str_w(space.getattr(w_node, space.wrap('id')))
+        ctx = expr_context.from_object(space, space.getattr(w_node, space.wrap('ctx')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Name(id, ctx, lineno, col_offset)
 
 State.ast_type('Name', 'expr')
 
@@ -1864,13 +2319,21 @@
         space.setattr(w_node, space.wrap('elts'), w_elts)
         w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
         space.setattr(w_node, space.wrap('ctx'), w_ctx)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        elts = space.getattr(w_node, space.wrap('elts'))
-        ctx = space.getattr(w_node, space.wrap('ctx'))
-        return List(elts, ctx)
+        elts_w = space.unpackiterable(
+                get_field(space, w_node, 'elts', False))
+        elts = [expr.from_object(space, w_item) for w_item in elts_w]
+        ctx = expr_context.from_object(space, space.getattr(w_node, space.wrap('ctx')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return List(elts, ctx, lineno, col_offset)
 
 State.ast_type('List', 'expr')
 
@@ -1900,13 +2363,21 @@
         space.setattr(w_node, space.wrap('elts'), w_elts)
         w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
         space.setattr(w_node, space.wrap('ctx'), w_ctx)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        elts = space.getattr(w_node, space.wrap('elts'))
-        ctx = space.getattr(w_node, space.wrap('ctx'))
-        return Tuple(elts, ctx)
+        elts_w = space.unpackiterable(
+                get_field(space, w_node, 'elts', False))
+        elts = [expr.from_object(space, w_item) for w_item in elts_w]
+        ctx = expr_context.from_object(space, space.getattr(w_node, space.wrap('ctx')))
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Tuple(elts, ctx, lineno, col_offset)
 
 State.ast_type('Tuple', 'expr')
 
@@ -1927,18 +2398,39 @@
         w_node = space.call_function(get(space).w_Const)
         w_value = self.value  # object
         space.setattr(w_node, space.wrap('value'), w_value)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
         value = space.getattr(w_node, space.wrap('value'))
-        return Const(value)
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return Const(value, lineno, col_offset)
 
 State.ast_type('Const', 'expr')
 
 
 class expr_context(AST):
-    pass
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_Load):
+            return 1
+        if space.isinstance_w(w_node, get(space).w_Store):
+            return 2
+        if space.isinstance_w(w_node, get(space).w_Del):
+            return 3
+        if space.isinstance_w(w_node, get(space).w_AugLoad):
+            return 4
+        if space.isinstance_w(w_node, get(space).w_AugStore):
+            return 5
+        if space.isinstance_w(w_node, get(space).w_Param):
+            return 6
+        raise operationerrfmt(space.w_TypeError,
+                "Expected expr_context node, got %T", w_node)
 State.ast_type('expr_context', 'AST')
 
 class _Load(expr_context):
@@ -1988,7 +2480,18 @@
 ]
 
 class slice(AST):
-    pass
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_Ellipsis):
+            return Ellipsis.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Slice):
+            return Slice.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_ExtSlice):
+            return ExtSlice.from_object(space, w_node)
+        if space.isinstance_w(w_node, get(space).w_Index):
+            return Index.from_object(space, w_node)
+        raise operationerrfmt(space.w_TypeError,
+                "Expected slice node, got %T", w_node)
 State.ast_type('slice', 'AST')
 
 class Ellipsis(slice):
@@ -2042,9 +2545,9 @@
 
     @staticmethod
     def from_object(space, w_node):
-        lower = space.getattr(w_node, space.wrap('lower'))
-        upper = space.getattr(w_node, space.wrap('upper'))
-        step = space.getattr(w_node, space.wrap('step'))
+        lower = expr.from_object(space, space.getattr(w_node, space.wrap('lower')))
+        upper = expr.from_object(space, space.getattr(w_node, space.wrap('upper')))
+        step = expr.from_object(space, space.getattr(w_node, space.wrap('step')))
         return Slice(lower, upper, step)
 
 State.ast_type('Slice', 'slice')
@@ -2075,7 +2578,9 @@
 
     @staticmethod
     def from_object(space, w_node):
-        dims = space.getattr(w_node, space.wrap('dims'))
+        dims_w = space.unpackiterable(
+                get_field(space, w_node, 'dims', False))
+        dims = [slice.from_object(space, w_item) for w_item in dims_w]
         return ExtSlice(dims)
 
 State.ast_type('ExtSlice', 'slice')
@@ -2101,14 +2606,21 @@
 
     @staticmethod
     def from_object(space, w_node):
-        value = space.getattr(w_node, space.wrap('value'))
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
         return Index(value)
 
 State.ast_type('Index', 'slice')
 
 
 class boolop(AST):
-    pass
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_And):
+            return 1
+        if space.isinstance_w(w_node, get(space).w_Or):
+            return 2
+        raise operationerrfmt(space.w_TypeError,
+                "Expected boolop node, got %T", w_node)
 State.ast_type('boolop', 'AST')
 
 class _And(boolop):
@@ -2130,7 +2642,34 @@
 ]
 
 class operator(AST):
-    pass
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_Add):
+            return 1
+        if space.isinstance_w(w_node, get(space).w_Sub):
+            return 2
+        if space.isinstance_w(w_node, get(space).w_Mult):
+            return 3
+        if space.isinstance_w(w_node, get(space).w_Div):
+            return 4
+        if space.isinstance_w(w_node, get(space).w_Mod):
+            return 5
+        if space.isinstance_w(w_node, get(space).w_Pow):
+            return 6
+        if space.isinstance_w(w_node, get(space).w_LShift):
+            return 7
+        if space.isinstance_w(w_node, get(space).w_RShift):
+            return 8
+        if space.isinstance_w(w_node, get(space).w_BitOr):
+            return 9
+        if space.isinstance_w(w_node, get(space).w_BitXor):
+            return 10
+        if space.isinstance_w(w_node, get(space).w_BitAnd):
+            return 11
+        if space.isinstance_w(w_node, get(space).w_FloorDiv):
+            return 12
+        raise operationerrfmt(space.w_TypeError,
+                "Expected operator node, got %T", w_node)
 State.ast_type('operator', 'AST')
 
 class _Add(operator):
@@ -2222,7 +2761,18 @@
 ]
 
 class unaryop(AST):
-    pass
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_Invert):
+            return 1
+        if space.isinstance_w(w_node, get(space).w_Not):
+            return 2
+        if space.isinstance_w(w_node, get(space).w_UAdd):
+            return 3
+        if space.isinstance_w(w_node, get(space).w_USub):
+            return 4
+        raise operationerrfmt(space.w_TypeError,
+                "Expected unaryop node, got %T", w_node)
 State.ast_type('unaryop', 'AST')
 
 class _Invert(unaryop):
@@ -2258,7 +2808,30 @@
 ]
 
 class cmpop(AST):
-    pass
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_Eq):
+            return 1
+        if space.isinstance_w(w_node, get(space).w_NotEq):
+            return 2
+        if space.isinstance_w(w_node, get(space).w_Lt):
+            return 3
+        if space.isinstance_w(w_node, get(space).w_LtE):
+            return 4
+        if space.isinstance_w(w_node, get(space).w_Gt):
+            return 5
+        if space.isinstance_w(w_node, get(space).w_GtE):
+            return 6
+        if space.isinstance_w(w_node, get(space).w_Is):
+            return 7
+        if space.isinstance_w(w_node, get(space).w_IsNot):
+            return 8
+        if space.isinstance_w(w_node, get(space).w_In):
+            return 9
+        if space.isinstance_w(w_node, get(space).w_NotIn):
+            return 10
+        raise operationerrfmt(space.w_TypeError,
+                "Expected cmpop node, got %T", w_node)
 State.ast_type('cmpop', 'AST')
 
 class _Eq(cmpop):
@@ -2368,9 +2941,11 @@
 
     @staticmethod
     def from_object(space, w_node):
-        target = space.getattr(w_node, space.wrap('target'))
-        iter = space.getattr(w_node, space.wrap('iter'))
-        ifs = space.getattr(w_node, space.wrap('ifs'))
+        target = expr.from_object(space, space.getattr(w_node, space.wrap('target')))
+        iter = expr.from_object(space, space.getattr(w_node, space.wrap('iter')))
+        ifs_w = space.unpackiterable(
+                get_field(space, w_node, 'ifs', False))
+        ifs = [expr.from_object(space, w_item) for w_item in ifs_w]
         return comprehension(target, iter, ifs)
 
 State.ast_type('comprehension', 'AST')
@@ -2380,6 +2955,13 @@
     def __init__(self, lineno, col_offset):
         self.lineno = lineno
         self.col_offset = col_offset
+
+    @staticmethod
+    def from_object(space, w_node):
+        if space.isinstance_w(w_node, get(space).w_ExceptHandler):
+            return ExceptHandler.from_object(space, w_node)
+        raise operationerrfmt(space.w_TypeError,
+                "Expected excepthandler node, got %T", w_node)
 State.ast_type('excepthandler', 'AST')
 
 class ExceptHandler(excepthandler):
@@ -2414,14 +2996,22 @@
             body_w = [node.to_object(space) for node in self.body] # stmt
         w_body = space.newlist(body_w)
         space.setattr(w_node, space.wrap('body'), w_body)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
-        type = space.getattr(w_node, space.wrap('type'))
-        name = space.getattr(w_node, space.wrap('name'))
-        body = space.getattr(w_node, space.wrap('body'))
-        return ExceptHandler(type, name, body)
+        type = expr.from_object(space, space.getattr(w_node, space.wrap('type')))
+        name = expr.from_object(space, space.getattr(w_node, space.wrap('name')))
+        body_w = space.unpackiterable(
+                get_field(space, w_node, 'body', False))
+        body = [stmt.from_object(space, w_item) for w_item in body_w]
+        lineno = space.int_w(space.getattr(w_node, space.wrap('lineno')))
+        col_offset = space.int_w(space.getattr(w_node, space.wrap('col_offset')))
+        return ExceptHandler(type, name, body, lineno, col_offset)
 
 State.ast_type('ExceptHandler', 'excepthandler')
 
@@ -2466,10 +3056,14 @@
 
     @staticmethod
     def from_object(space, w_node):
-        args = space.getattr(w_node, space.wrap('args'))
-        vararg = space.getattr(w_node, space.wrap('vararg'))
-        kwarg = space.getattr(w_node, space.wrap('kwarg'))
-        defaults = space.getattr(w_node, space.wrap('defaults'))
+        args_w = space.unpackiterable(
+                get_field(space, w_node, 'args', False))
+        args = [expr.from_object(space, w_item) for w_item in args_w]
+        vararg = space.str_w(space.getattr(w_node, space.wrap('vararg')))
+        kwarg = space.str_w(space.getattr(w_node, space.wrap('kwarg')))
+        defaults_w = space.unpackiterable(
+                get_field(space, w_node, 'defaults', False))
+        defaults = [expr.from_object(space, w_item) for w_item in defaults_w]
         return arguments(args, vararg, kwarg, defaults)
 
 State.ast_type('arguments', 'AST')
@@ -2497,8 +3091,8 @@
 
     @staticmethod
     def from_object(space, w_node):
-        arg = space.getattr(w_node, space.wrap('arg'))
-        value = space.getattr(w_node, space.wrap('value'))
+        arg = space.str_w(space.getattr(w_node, space.wrap('arg')))
+        value = expr.from_object(space, space.getattr(w_node, space.wrap('value')))
         return keyword(arg, value)
 
 State.ast_type('keyword', 'AST')
@@ -2525,8 +3119,8 @@
 
     @staticmethod
     def from_object(space, w_node):
-        name = space.getattr(w_node, space.wrap('name'))
-        asname = space.getattr(w_node, space.wrap('asname'))
+        name = space.str_w(space.getattr(w_node, space.wrap('name')))
+        asname = space.str_w(space.getattr(w_node, space.wrap('asname')))
         return alias(name, asname)
 
 State.ast_type('alias', 'AST')
diff --git a/pypy/interpreter/astcompiler/test/test_ast.py b/pypy/interpreter/astcompiler/test/test_ast.py
--- a/pypy/interpreter/astcompiler/test/test_ast.py
+++ b/pypy/interpreter/astcompiler/test/test_ast.py
@@ -32,6 +32,6 @@
         value = space.wrap(42)
         w_node = space.call_function(ast.get(space).w_Num)
         space.setattr(w_node, space.wrap('n'), value)
-        node = ast.Num.from_object(space, w_node)
+        node = ast.Num.from_object(space, w_node, lineno=1, col_offset=1)
         assert node.n is value
         
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -57,7 +57,14 @@
     def visitSum(self, sum, base):
         if is_simple_sum(sum):
             self.emit("class %s(AST):" % (base,))
-            self.emit("pass", 1)
+            self.emit("@staticmethod", 1)
+            self.emit("def from_object(space, w_node):", 1)
+            for i, cons in enumerate(sum.types):
+                self.emit("if space.isinstance_w(w_node, get(space).w_%s):"
+                          % (cons.name,), 2)
+                self.emit("return %i" % (i+1,), 3)
+            self.emit("raise operationerrfmt(space.w_TypeError,", 2)
+            self.emit("        \"Expected %s node, got %%T\", w_node)" % (base,), 2)
             self.emit("State.ast_type('%s', 'AST')" % (base,))
             self.emit("")
             for i, cons in enumerate(sum.types):
@@ -82,8 +89,16 @@
                 self.emit("def __init__(self, %s):" % (args,), 1)
                 for attr in sum.attributes:
                     self.visit(attr)
-            else:
-                self.emit("pass", 1)
+                self.emit("")
+            self.emit("@staticmethod", 1)
+            self.emit("def from_object(space, w_node):", 1)
+            for typ in sum.types:
+                self.emit("if space.isinstance_w(w_node, get(space).w_%s):"
+                          % (typ.name,), 2)
+                self.emit("return %s.from_object(space, w_node)"
+                          % (typ.name,), 3)
+            self.emit("raise operationerrfmt(space.w_TypeError,", 2)
+            self.emit("        \"Expected %s node, got %%T\", w_node)" % (base,), 2)
             self.emit("State.ast_type('%r', 'AST')" % (base,))
             self.emit("")
             for cons in sum.types:
@@ -113,6 +128,20 @@
         else:
             return "%s.to_object(space)" % (value,)
 
+    def get_value_extractor(self, field, value):
+        if field.type.value in self.data.simple_types:
+            return "%s.from_object(space, %s)" % (field.type, value)
+        elif field.type.value in ("object",):
+            return value
+        elif field.type.value in ("string",):
+            return "check_string(space, %s)" % (value,)
+        elif field.type.value in ("identifier",):
+            return "space.str_w(%s)" % (value,)
+        elif field.type.value in ("int",):
+            return "space.int_w(%s)" % (value,)
+        else:
+            return "%s.from_object(space, %s)" % (field.type, value)
+
     def get_field_converter(self, field):
         if field.seq:
             lines = []
@@ -129,13 +158,26 @@
             return ["w_%s = %s  # %s" % (field.name, wrapper, field.type)]
 
     def get_field_extractor(self, field):
-        lines = ["%s = space.getattr(w_node, space.wrap('%s'))" % (field.name, field.name)]
+        if field.seq:
+            lines = []
+            lines.append("%s_w = space.unpackiterable(" % (field.name,))
+            lines.append("        get_field(space, w_node, '%s', %s))"
+                         % (field.name, field.opt))
+            value = self.get_value_extractor(field, "w_item")
+            lines.append("%s = [%s for w_item in %s_w]" %
+                         (field.name, value, field.name))
+        else:
+            value = self.get_value_extractor(
+                field, 
+                "space.getattr(w_node, space.wrap('%s'))" % (field.name,))
+            lines = ["%s = %s" % (field.name, value)]
         return lines
 
-    def make_converters(self, fields, name):
+    def make_converters(self, fields, name, extras=None):
         self.emit("def to_object(self, space):", 1)
         self.emit("w_node = space.call_function(get(space).w_%s)" % name, 2)
-        for field in fields:
+        all_fields = fields + extras if extras else fields
+        for field in all_fields:
             wrapping_code = self.get_field_converter(field)
             for line in wrapping_code:
                 self.emit(line, 2)
@@ -145,12 +187,12 @@
         self.emit("")
         self.emit("@staticmethod", 1)
         self.emit("def from_object(space, w_node):", 1)
-        for field in fields:
+        for field in all_fields:
             unwrapping_code = self.get_field_extractor(field)
             for line in unwrapping_code:
                 self.emit(line, 2)
         self.emit("return %s(%s)" % (
-                name, ', '.join(str(field.name) for field in fields)), 2)
+                name, ', '.join(str(field.name) for field in all_fields)), 2)
         self.emit("")
 
     def make_constructor(self, fields, node, extras=None, base=None):
@@ -193,7 +235,7 @@
         self.emit("visitor.visit_%s(self)" % (cons.name,), 2)
         self.emit("")
         self.make_mutate_over(cons, cons.name)
-        self.make_converters(cons.fields, cons.name)
+        self.make_converters(cons.fields, cons.name, extra_attributes)
         self.emit("State.ast_type('%r', '%s')" % (cons.name, base))
         self.emit("")
 
@@ -327,15 +369,30 @@
         self.optional_masks = optional_masks
 
 
-HEAD = """# Generated by tools/asdl_py.py
-from pypy.interpreter.error import OperationError
-from rpython.tool.pairtype import extendabletype
+HEAD = r"""# Generated by tools/asdl_py.py
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter import typedef
 from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.error import OperationError, operationerrfmt
+from rpython.tool.pairtype import extendabletype
 from rpython.tool.sourcetools import func_with_new_name
 
 
+def check_string(space, w_obj):
+    if not (space.isinstance_w(w_obj, space.w_str) or
+            space.isinstance_w(w_obj, space.w_unicode)):
+        raise OperationError(space.w_TypeError, space.wrap(
+                'AST string must be of type str or unicode'))
+    return w_obj
+
+def get_field(space, w_node, name, optional):
+    w_obj = w_node.getdictvalue(space, name)
+    if w_obj is None and not optional:
+        raise operationerrfmt(space.w_TypeError,
+                "required field \"%s\" missing from %T", name, w_node)
+    return w_obj
+
+
 class AST(object):
     __metaclass__ = extendabletype
 
@@ -363,13 +420,6 @@
 class W_AST(W_Root):
     w_dict = None
 
-    def obj2mod(self, space):
-        if space.isinstance_w(self, get(space).w_Module):
-            return Module.from_object(space, self)
-        else:
-            raise OperationError(space.w_TypeError, space.wrap(
-                    "Expected mod node"))
-
     def getdict(self, space):
         if self.w_dict is None:
             self.w_dict = space.newdict(instance=True)
diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -28,7 +28,7 @@
     w_ast_type = space.gettypeobject(ast.W_AST.typedef)
     str_ = None
     if space.isinstance_w(w_source, w_ast_type):
-        ast_node = space.interp_w(ast.W_AST, w_source).obj2mod(space)
+        ast_node = ast.mod.from_object(space, w_source)
     elif space.isinstance_w(w_source, space.w_unicode):
         w_utf_8_source = space.call_method(w_source, "encode",
                                            space.wrap("utf-8"))


More information about the pypy-commit mailing list