Index: Python/getargs.c
===================================================================
--- Python/getargs.c	(revision 57622)
+++ Python/getargs.c	(working copy)
@@ -921,6 +921,34 @@
 		break;
 	}
 	
+	case 'Z': {/* unicode, may be NULL (None) */
+		if (*format == '#') { /* any buffer-like object */
+			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+			FETCH_SIZE;
+			
+			if (arg == Py_None) {
+				*p = 0;
+				STORE_SIZE(0);
+			}
+			else if (PyUnicode_Check(arg)) {
+				*p = PyUnicode_AS_UNICODE(arg);
+				STORE_SIZE(PyUnicode_GET_SIZE(arg));
+			}
+			format++;
+		} else {
+			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+			
+			if (arg == Py_None)
+				*p = 0;
+			else if (PyUnicode_Check(arg))
+				*p = PyUnicode_AS_UNICODE(arg);
+			else
+				return converterr("string or None", 
+						  arg, msgbuf, bufsize);
+		}
+		break;
+	}
+	
 	case 'e': {/* encoded string */
 		char **buffer;
 		const char *encoding;
Index: Doc/c-api/utilities.rst
===================================================================
--- Doc/c-api/utilities.rst	(revision 57622)
+++ Doc/c-api/utilities.rst	(working copy)
@@ -484,6 +484,13 @@
    by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE`
    array.
 
+``Z`` (Unicode or ``None``) [Py_UNICODE \*]
+   Like ``s``, but the Python object may also be ``None``, in which case the C
+   pointer is set to *NULL*.
+
+``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int]
+   This is to ``u#`` as ``Z`` is to ``u``.
+
 ``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer]
    This variant on ``s`` is used for encoding Unicode and objects convertible to
    Unicode into a character buffer. It only works for encoded data without embedded
Index: Modules/_fileio.c
===================================================================
--- Modules/_fileio.c	(revision 57622)
+++ Modules/_fileio.c	(working copy)
@@ -45,7 +45,7 @@
 internal_close(PyFileIOObject *self)
 {
 	int save_errno = 0;
-	if (self->fd >= 0) {
+	if (self->fd >= 3) {
 		int fd = self->fd;
 		self->fd = -1;
 		Py_BEGIN_ALLOW_THREADS
Index: Modules/_testcapimodule.c
===================================================================
--- Modules/_testcapimodule.c	(revision 57622)
+++ Modules/_testcapimodule.c	(working copy)
@@ -497,7 +497,60 @@
 	return Py_None;
 }
 
+/* Test Z and Z# codes for PyArg_ParseTuple */
 static PyObject *
+test_Z_code(PyObject *self)
+{
+	PyObject *tuple, *obj;
+	Py_UNICODE *value1, *value2;
+	int len1, len2;
+
+        tuple = PyTuple_New(2);
+        if (tuple == NULL)
+        	return NULL;
+
+	obj = PyUnicode_FromString("test");
+	PyTuple_SET_ITEM(tuple, 0, obj);
+	Py_INCREF(Py_None);
+	PyTuple_SET_ITEM(tuple, 1, Py_None);
+
+	/* swap values on purpose */
+        value1 = NULL;
+	value2 = PyUnicode_AS_UNICODE(obj);
+
+	/* Test Z for both values */
+        if (PyArg_ParseTuple(tuple, "ZZ:test_Z_code", &value1, &value2) < 0)
+		return NULL;
+        if (value1 != PyUnicode_AS_UNICODE(obj))
+        	return raiseTestError("test_Z_code",
+			"Z code returned wrong value for 'test'");
+        if (value2 != NULL)
+        	return raiseTestError("test_Z_code",
+			"Z code returned wrong value for None");
+
+        value1 = NULL;
+	value2 = PyUnicode_AS_UNICODE(obj);
+	len1 = -1;
+	len2 = -1;
+
+	/* Test Z# for both values */
+        if (PyArg_ParseTuple(tuple, "Z#Z#:test_Z_code", &value1, &len1, 
+			     &value2, &len2) < 0)
+        	return NULL;
+        if (value1 != PyUnicode_AS_UNICODE(obj) ||
+	    len1 != PyUnicode_GET_SIZE(obj))
+        	return raiseTestError("test_Z_code",
+			"Z# code returned wrong values for 'test'");
+        if (value2 != NULL ||
+	    len2 != 0)
+        	return raiseTestError("test_Z_code",
+			"Z# code returned wrong values for None'");
+
+	Py_DECREF(tuple);
+	Py_RETURN_NONE;
+}
+
+static PyObject *
 codec_incrementalencoder(PyObject *self, PyObject *args)
 {
 	const char *encoding, *errors = NULL;
@@ -862,6 +915,7 @@
 	 (PyCFunction)codec_incrementaldecoder,	 METH_VARARGS},
 #endif
 	{"test_u_code",		(PyCFunction)test_u_code,	 METH_NOARGS},
+	{"test_Z_code",		(PyCFunction)test_Z_code,	 METH_NOARGS},
 #ifdef WITH_THREAD
 	{"_test_thread_state",  test_thread_state, 		 METH_VARARGS},
 #endif
