Merged revisions 62039-62042 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r62039 | georg.brandl | 2008-03-29 06:24:23 -0700 (Sat, 29 Mar 2008) | 3 lines

  Properly check for consistency with the third argument of
  compile() when compiling an AST node.
........
  r62040 | amaury.forgeotdarc | 2008-03-29 06:47:05 -0700 (Sat, 29 Mar 2008) | 5 lines

  The buildbot "x86 W2k8 trunk" seems to hang in test_socket.
  http://www.python.org/dev/buildbot/trunk/x86%20W2k8%20trunk/builds/255/step-test/0

  Temporarily increase verbosity of this test.
........
  r62042 | amaury.forgeotdarc | 2008-03-29 07:53:05 -0700 (Sat, 29 Mar 2008) | 3 lines

  Still investigating on the hanging test_socket.
  the test itself doesn't do anything on windows, focus on setUp and tearDown.
........
diff --git a/Include/Python-ast.h b/Include/Python-ast.h
index c018ddd..6653b08 100644
--- a/Include/Python-ast.h
+++ b/Include/Python-ast.h
@@ -542,5 +542,5 @@
 alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena);
 
 PyObject* PyAST_mod2obj(mod_ty t);
-mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena);
+mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);
 int PyAST_Check(PyObject* obj);
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 376369b..5a069d3 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -427,6 +427,20 @@
             self.assert_(type(ast) == _ast.Module)
             co2 = compile(ast, '%s3' % fname, 'exec')
             self.assertEqual(co1, co2)
+            # the code object's filename comes from the second compilation step
+            self.assertEqual(co2.co_filename, '%s3' % fname)
+
+        # raise exception when node type doesn't match with compile mode
+        co1 = compile('print(1)', '<string>', 'exec', _ast.PyCF_ONLY_AST)
+        self.assertRaises(TypeError, compile, co1, '<ast>', 'eval')
+
+        # raise exception when node type is no start node
+        self.assertRaises(TypeError, compile, _ast.If(), '<ast>', 'exec')
+
+        # raise exception when node has invalid children
+        ast = _ast.Module()
+        ast.body = [_ast.BoolOp()]
+        self.assertRaises(TypeError, compile, ast, '<ast>', 'exec')
 
 
 def test_main():
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 2bec373..f4abffa 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -15,6 +15,14 @@
 from weakref import proxy
 import signal
 
+# Temporary hack to see why test_socket hangs on one buildbot
+if os.environ.get('COMPUTERNAME') == "GRAPE":
+    def verbose_write(arg):
+        print(arg, file=sys.__stdout__)
+else:
+    def verbose_write(arg):
+        pass
+
 PORT = 50007
 HOST = 'localhost'
 MSG = b'Michael Gilfix was here\n'
@@ -22,15 +30,21 @@
 class SocketTCPTest(unittest.TestCase):
 
     def setUp(self):
+        verbose_write(self)
         self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        verbose_write(str(self) + " socket created")
         global PORT
         PORT = test_support.bind_port(self.serv, HOST, PORT)
+        verbose_write(str(self) + " start listening")
         self.serv.listen(1)
+        verbose_write(str(self) + " started")
 
     def tearDown(self):
+        verbose_write(str(self) + " close")
         self.serv.close()
         self.serv = None
+        verbose_write(str(self) + " done")
 
 class SocketUDPTest(unittest.TestCase):
 
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index 94e04b1..1b5e18f 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -934,13 +934,20 @@
     return ast2obj_mod(t);
 }
 
-mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena)
+/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
+mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
 {
     mod_ty res;
+    PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type,
+                            (PyObject*)Interactive_type};
+    char *req_name[] = {"Module", "Expression", "Interactive"};
+    assert(0 <= mode && mode <= 2);
+
     init_types();
-    if (!PyObject_IsInstance(ast, (PyObject*)mod_type)) {
-        PyErr_SetString(PyExc_TypeError, "expected either Module, Interactive "
-                        "or Expression node");
+
+    if (!PyObject_IsInstance(ast, req_type[mode])) {
+        PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s",
+                     req_name[mode], Py_TYPE(ast)->tp_name);
         return NULL;
     }
     if (obj2ast_mod(ast, &res, arena) != 0)
@@ -997,8 +1004,8 @@
                             )
         c.visit(mod)
         f.write("PyObject* PyAST_mod2obj(mod_ty t);\n")
-        print >>f, "mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena);"
-        print >>f, "int PyAST_Check(PyObject* obj);"
+        f.write("mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);\n")
+        f.write("int PyAST_Check(PyObject* obj);\n")
         f.close()
 
     if SRC_DIR:
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 464d28d..9f85581 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -6415,13 +6415,20 @@
     return ast2obj_mod(t);
 }
 
-mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena)
+/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
+mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
 {
     mod_ty res;
+    PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type,
+                            (PyObject*)Interactive_type};
+    char *req_name[] = {"Module", "Expression", "Interactive"};
+    assert(0 <= mode && mode <= 2);
+
     init_types();
-    if (!PyObject_IsInstance(ast, (PyObject*)mod_type)) {
-        PyErr_SetString(PyExc_TypeError, "expected either Module, Interactive "
-                        "or Expression node");
+
+    if (!PyObject_IsInstance(ast, req_type[mode])) {
+        PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s",
+                     req_name[mode], Py_TYPE(ast)->tp_name);
         return NULL;
     }
     if (obj2ast_mod(ast, &res, arena) != 0)
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index ccfce06..199ebc0 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -513,13 +513,14 @@
 	char *str;
 	char *filename;
 	char *startstr;
-	int start;
+	int mode = -1;
 	int dont_inherit = 0;
 	int supplied_flags = 0;
 	PyCompilerFlags cf;
 	PyObject *cmd;
 	static char *kwlist[] = {"source", "filename", "mode", "flags",
 				 "dont_inherit", NULL};
+	int start[] = {Py_file_input, Py_eval_input, Py_single_input};
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oss|ii:compile",
 					 kwlist, &cmd, &filename, &startstr,
@@ -541,6 +542,18 @@
 		PyEval_MergeCompilerFlags(&cf);
 	}
 
+	if (strcmp(startstr, "exec") == 0)
+		mode = 0;
+	else if (strcmp(startstr, "eval") == 0)
+		mode = 1;
+	else if (strcmp(startstr, "single") == 0)
+		mode = 2;
+	else {
+		PyErr_SetString(PyExc_ValueError,
+				"compile() arg 3 must be 'exec', 'eval' or 'single'");
+		return NULL;
+	}
+
 	if (PyAST_Check(cmd)) {
 		PyObject *result;
 		if (supplied_flags & PyCF_ONLY_AST) {
@@ -552,7 +565,7 @@
 			mod_ty mod;
 
 			arena = PyArena_New();
-			mod = PyAST_obj2mod(cmd, arena);
+			mod = PyAST_obj2mod(cmd, arena, mode);
 			if (mod == NULL) {
 				PyArena_Free(arena);
 				return NULL;
@@ -564,25 +577,11 @@
 		return result;
 	}
 
-	/* XXX: is it possible to pass start to the PyAST_ branch? */
-	if (strcmp(startstr, "exec") == 0)
-		start = Py_file_input;
-	else if (strcmp(startstr, "eval") == 0)
-		start = Py_eval_input;
-	else if (strcmp(startstr, "single") == 0)
-		start = Py_single_input;
-	else {
-		PyErr_SetString(PyExc_ValueError,
-				"compile() arg 3 must be 'exec'"
-				"or 'eval' or 'single'");
-		return NULL;
-	}
-
 	str = source_as_string(cmd);
 	if (str == NULL)
 		return NULL;
 
-	return Py_CompileStringFlags(str, filename, start, &cf);
+	return Py_CompileStringFlags(str, filename, start[mode], &cf);
 }
 
 PyDoc_STRVAR(compile_doc,