Backport of the print function, using a __future__ import.
This work is substantially Anthony Baxter's, from issue
1633807.  I just freshened it, made a few minor tweaks,
and added the test cases.  I also created issue 2412,
which is to check for 2to3's behavior with the print
function.  I also added myself to ACKS.
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 228bb2d..0c3d6e2 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1486,6 +1486,78 @@
 equivalent to (x**y) % z, but may be more efficient (e.g. for longs).");
 
 
+static PyObject *
+builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	static char *kwlist[] = {"sep", "end", "file", 0};
+	static PyObject *dummy_args;
+	PyObject *sep = NULL, *end = NULL, *file = NULL;
+	int i, err;
+
+	if (dummy_args == NULL) {
+		if (!(dummy_args = PyTuple_New(0)))
+			return NULL;
+	}
+	if (!PyArg_ParseTupleAndKeywords(dummy_args, kwds, "|OOO:print",
+					 kwlist, &sep, &end, &file))
+		return NULL;
+	if (file == NULL || file == Py_None) {
+		file = PySys_GetObject("stdout");
+		/* sys.stdout may be None when FILE* stdout isn't connected */
+		if (file == Py_None)
+			Py_RETURN_NONE;
+	}
+
+	if (sep && sep != Py_None && !PyString_Check(sep) &&
+            !PyUnicode_Check(sep)) {
+		PyErr_Format(PyExc_TypeError,
+			     "sep must be None, str or unicode, not %.200s",
+			     sep->ob_type->tp_name);
+		return NULL;
+	}
+	if (end && end != Py_None && !PyString_Check(end) &&
+	    !PyUnicode_Check(end)) {
+		PyErr_Format(PyExc_TypeError,
+			     "end must be None, str or unicode, not %.200s",
+			     end->ob_type->tp_name);
+		return NULL;
+	}
+
+	for (i = 0; i < PyTuple_Size(args); i++) {
+		if (i > 0) {
+			if (sep == NULL || sep == Py_None)
+				err = PyFile_WriteString(" ", file);
+			else
+				err = PyFile_WriteObject(sep, file,
+							 Py_PRINT_RAW);
+			if (err)
+				return NULL;
+		}
+		err = PyFile_WriteObject(PyTuple_GetItem(args, i), file,
+					 Py_PRINT_RAW);
+		if (err)
+			return NULL;
+	}
+
+	if (end == NULL || end == Py_None)
+		err = PyFile_WriteString("\n", file);
+	else
+		err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
+	if (err)
+		return NULL;
+
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(print_doc,
+"print(value, ..., sep=' ', end='\\n', file=sys.stdout)\n\
+\n\
+Prints the values to a stream, or to sys.stdout by default.\n\
+Optional keyword arguments:\n\
+file: a file-like object (stream); defaults to the current sys.stdout.\n\
+sep:  string inserted between values, default a space.\n\
+end:  string appended after the last value, default a newline.");
+
 
 /* Return number of items in range (lo, hi, step), when arguments are
  * PyInt or PyLong objects.  step > 0 required.  Return a value < 0 if
@@ -2424,6 +2496,7 @@
  	{"open",	(PyCFunction)builtin_open,       METH_VARARGS | METH_KEYWORDS, open_doc},
  	{"ord",		builtin_ord,        METH_O, ord_doc},
  	{"pow",		builtin_pow,        METH_VARARGS, pow_doc},
+ 	{"print",	(PyCFunction)builtin_print,      METH_VARARGS | METH_KEYWORDS, print_doc},
  	{"range",	builtin_range,      METH_VARARGS, range_doc},
  	{"raw_input",	builtin_raw_input,  METH_VARARGS, raw_input_doc},
  	{"reduce",	builtin_reduce,     METH_VARARGS, reduce_doc},
diff --git a/Python/future.c b/Python/future.c
index af1e1cc..267e1b7 100644
--- a/Python/future.c
+++ b/Python/future.c
@@ -33,6 +33,8 @@
 			ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
 		} else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
 			ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
+		} else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
+			ff->ff_features |= CO_FUTURE_PRINT_FUNCTION;
 		} else if (strcmp(feature, "braces") == 0) {
 			PyErr_SetString(PyExc_SyntaxError,
 					"not a chance");
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 298d218..b8d516d 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -738,18 +738,19 @@
 	}
 }
 
+#if 0
 /* compute parser flags based on compiler flags */
 #define PARSER_FLAGS(flags) \
 	((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
 		      PyPARSE_DONT_IMPLY_DEDENT : 0)) : 0)
-
-#if 0
+#endif
+#if 1
 /* Keep an example of flags with future keyword support. */
 #define PARSER_FLAGS(flags) \
 	((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
 		      PyPARSE_DONT_IMPLY_DEDENT : 0) \
-		    | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \
-		       PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
+		    | ((flags)->cf_flags & CO_FUTURE_PRINT_FUNCTION ? \
+		       PyPARSE_PRINT_IS_FUNCTION : 0)) : 0)
 #endif
 
 int