Christian Heimes added the comment:

The new patch fixes the startup problem with pythonw.exe on Windows. I
still wonder if print(sometest) is raising an exception when stdout is
not available.

Added file: http://bugs.python.org/file8731/py3k_fileio_fixes.patch

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1415>
__________________________________
Index: Modules/_fileio.c
===================================================================
--- Modules/_fileio.c	(revision 58930)
+++ Modules/_fileio.c	(working copy)
@@ -7,6 +7,8 @@
 #include <fcntl.h>
 #include <stddef.h> /* For offsetof */
 
+#define INVALID_FD -0xFABC
+
 /*
  * Known likely problems:
  *
@@ -30,10 +32,11 @@
 typedef struct {
 	PyObject_HEAD
 	int fd;
+	int closed : 1;
 	unsigned readable : 1;
 	unsigned writable : 1;
 	int seekable : 2; /* -1 means unknown */
-	int closefd : 1;
+	int close_fd : 1;
 	PyObject *weakreflist;
 } PyFileIOObject;
 
@@ -46,9 +49,15 @@
 internal_close(PyFileIOObject *self)
 {
 	int save_errno = 0;
+
+	if (self->closed) {
+		return save_errno;
+	}
+	self->closed = 1;
+
 	if (self->fd >= 0) {
 		int fd = self->fd;
-		self->fd = -1;
+		self->fd = INVALID_FD;
 		Py_BEGIN_ALLOW_THREADS
 		if (close(fd) < 0)
 			save_errno = errno;
@@ -60,7 +69,7 @@
 static PyObject *
 fileio_close(PyFileIOObject *self)
 {
-	if (!self->closefd) {
+	if (!self->close_fd) {
 		if (PyErr_WarnEx(PyExc_RuntimeWarning,
 				 "Trying to close unclosable fd!", 3) < 0) {
 			return NULL;
@@ -86,6 +95,7 @@
 	self = (PyFileIOObject *) type->tp_alloc(type, 0);
 	if (self != NULL) {
 		self->fd = -1;
+		self->closed = 0;
 		self->weakreflist = NULL;
 	}
 
@@ -127,7 +137,7 @@
 fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
 {
 	PyFileIOObject *self = (PyFileIOObject *) oself;
-	static char *kwlist[] = {"file", "mode", "closefd", NULL};
+	static char *kwlist[] = {"file", "mode", "close_fd", NULL};
 	char *name = NULL;
 	char *mode = "r";
 	char *s;
@@ -137,8 +147,8 @@
 	int ret = 0;
 	int rwa = 0, plus = 0, append = 0;
 	int flags = 0;
-	int fd = -1;
-	int closefd = 1;
+	int fd = INVALID_FD;
+	int close_fd = 1;
 
 	assert(PyFileIO_Check(oself));
 	if (self->fd >= 0) {
@@ -148,12 +158,12 @@
 	}
 
 	if (PyArg_ParseTupleAndKeywords(args, kwds, "i|si:fileio",
-					kwlist, &fd, &mode, &closefd)) {
-		if (fd < 0) {
+					kwlist, &fd, &mode, &close_fd)) {
+		/*if (fd < 0) {
 			PyErr_SetString(PyExc_ValueError,
 					"Negative filedescriptor");
 			return -1;
-		}
+		}*/
 	}
 	else {
 		PyErr_Clear();
@@ -163,7 +173,7 @@
 		/* On NT, so wide API available */
 		PyObject *po;
 		if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:fileio",
-						kwlist, &po, &mode, &closefd)
+						kwlist, &po, &mode, &close_fd)
 						) {
 			widename = PyUnicode_AS_UNICODE(po);
 		} else {
@@ -178,7 +188,7 @@
 		if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:fileio",
 						 kwlist,
 						 Py_FileSystemDefaultEncoding,
-						 &name, &mode, &closefd))
+						 &name, &mode, &close_fd))
 			goto error;
 	    }
 	}
@@ -245,15 +255,15 @@
 		flags |= O_APPEND;
 #endif
 
-	if (fd >= 0) {
+	if (fd != INVALID_FD) {
 		self->fd = fd;
-		self->closefd = closefd;
+		self->close_fd = close_fd;
 	}
 	else {
-		self->closefd = 1;
-		if (!closefd) {
+		self->close_fd = 1;
+		if (!close_fd) {
 			PyErr_SetString(PyExc_ValueError,
-                            "Cannot use closefd=True with file name");
+                            "Cannot use close_fd=True with file name");
 			goto error;
 		}
 
@@ -292,7 +302,7 @@
 	if (self->weakreflist != NULL)
 		PyObject_ClearWeakRefs((PyObject *) self);
 
-	if (self->fd >= 0 && self->closefd) {
+	if (self->fd >= 0 && self->close_fd) {
 		errno = internal_close(self);
 		if (errno < 0) {
 #ifdef HAVE_STRERROR
@@ -315,16 +325,44 @@
 }
 
 static PyObject *
+err_invalid(void)
+{
+#ifdef EBADF
+	errno = EBADF;
+	PyErr_SetFromErrno(PyExc_IOError);
+	return NULL;
+#else
+	PyErr_SetString(PyExc_IOError, "Bad file descriptor");
+	return NULL;
+#endif
+}
+
+static PyObject *
 err_mode(char *action)
 {
 	PyErr_Format(PyExc_ValueError, "File not open for %s", action);
 	return NULL;
 }
 
+int
+err_check(PyFileIOObject *self)
+{
+	if (self->closed) {
+		err_closed();
+		return 1;
+	}
+	if (self->fd < 0) {
+		err_invalid();
+		return 1;
+	}
+	return 0;
+}
+
 static PyObject *
 fileio_fileno(PyFileIOObject *self)
 {
-	if (self->fd < 0)
+	/* don't check for valid fd here */
+	if (self->closed)
 		return err_closed();
 	return PyInt_FromLong((long) self->fd);
 }
@@ -332,7 +370,8 @@
 static PyObject *
 fileio_readable(PyFileIOObject *self)
 {
-	if (self->fd < 0)
+	/* don't check for valid fd here */
+	if (self->closed)
 		return err_closed();
 	return PyBool_FromLong((long) self->readable);
 }
@@ -340,7 +379,8 @@
 static PyObject *
 fileio_writable(PyFileIOObject *self)
 {
-	if (self->fd < 0)
+	/* don't check for valid fd here */
+	if (self->closed)
 		return err_closed();
 	return PyBool_FromLong((long) self->writable);
 }
@@ -348,7 +388,8 @@
 static PyObject *
 fileio_seekable(PyFileIOObject *self)
 {
-	if (self->fd < 0)
+	/* don't check for valid fd here */
+	if (self->closed)
 		return err_closed();
 	if (self->seekable < 0) {
 		int ret;
@@ -369,8 +410,8 @@
 	char *ptr;
 	Py_ssize_t n;
 
-	if (self->fd < 0)
-		return err_closed();
+	if (err_check(self))
+		return NULL;
 	if (!self->readable)
 		return err_mode("reading");
 
@@ -456,8 +497,8 @@
 	Py_ssize_t size = -1;
 	PyObject *bytes;
 
-	if (self->fd < 0)
-		return err_closed();
+	if (err_check(self))
+		return NULL;
 	if (!self->readable)
 		return err_mode("reading");
 
@@ -501,8 +542,8 @@
 	Py_ssize_t n;
 	char *ptr;
 
-	if (self->fd < 0)
-		return err_closed();
+	if (err_check(self))
+		return NULL;
 	if (!self->writable)
 		return err_mode("writing");
 
@@ -593,8 +634,8 @@
 	PyObject *posobj;
 	int whence = 0;
 
-	if (self->fd < 0)
-		return err_closed();
+	if (err_check(self))
+		return NULL;
 
 	if (!PyArg_ParseTuple(args, "O|i", &posobj, &whence))
 		return NULL;
@@ -605,8 +646,8 @@
 static PyObject *
 fileio_tell(PyFileIOObject *self, PyObject *args)
 {
-	if (self->fd < 0)
-		return err_closed();
+	if (err_check(self))
+		return NULL;
 
 	return portable_lseek(self->fd, NULL, 1);
 }
@@ -618,11 +659,9 @@
 	PyObject *posobj = NULL;
 	Py_off_t pos;
 	int ret;
-	int fd;
 
-	fd = self->fd;
-	if (fd < 0)
-		return err_closed();
+	if (err_check(self))
+		return NULL;
 	if (!self->writable)
 		return err_mode("writing");
 
@@ -630,7 +669,7 @@
 		return NULL;
 
 	if (posobj == Py_None || posobj == NULL) {
-                posobj = portable_lseek(fd, NULL, 1);
+                posobj = portable_lseek(self->fd, NULL, 1);
                 if (posobj == NULL)
                   return NULL;
         }
@@ -665,7 +704,7 @@
 
 		/* Have to move current pos to desired endpoint on Windows. */
 		errno = 0;
-		pos2 = portable_lseek(fd, posobj, SEEK_SET);
+		pos2 = portable_lseek(self->fd, posobj, SEEK_SET);
 		if (pos2 == NULL) {
 			Py_DECREF(posobj);
 			Py_DECREF(oldposobj);
@@ -676,7 +715,7 @@
 		/* Truncate.  Note that this may grow the file! */
 		Py_BEGIN_ALLOW_THREADS
 		errno = 0;
-		hFile = (HANDLE)_get_osfhandle(fd);
+		hFile = (HANDLE)_get_osfhandle(self->fd);
 		ret = hFile == (HANDLE)-1;
 		if (ret == 0) {
 			ret = SetEndOfFile(hFile) == 0;
@@ -687,7 +726,7 @@
 
 		if (ret == 0) {
 			/* Move to the previous position in the file */
-			pos2 = portable_lseek(fd, oldposobj, SEEK_SET);
+			pos2 = portable_lseek(self->fd, oldposobj, SEEK_SET);
 			if (pos2 == NULL) {
 				Py_DECREF(posobj);
 				Py_DECREF(oldposobj);
@@ -700,7 +739,7 @@
 #else
 	Py_BEGIN_ALLOW_THREADS
 	errno = 0;
-	ret = ftruncate(fd, pos);
+	ret = ftruncate(self->fd, pos);
 	Py_END_ALLOW_THREADS
 #endif /* !MS_WINDOWS */
 
@@ -742,8 +781,10 @@
 {
 	long res;
 
-	if (self->fd < 0)
+	/* don't check for valid fd here */
+	if (self->closed)
 		return err_closed();
+
 	Py_BEGIN_ALLOW_THREADS
 	res = isatty(self->fd);
 	Py_END_ALLOW_THREADS
@@ -850,7 +891,7 @@
 static PyObject *
 get_closed(PyFileIOObject *self, void *closure)
 {
-	return PyBool_FromLong((long)(self->fd < 0));
+	return PyBool_FromLong((long)(self->closed));
 }
 
 static PyObject *
Index: Objects/fileobject.c
===================================================================
--- Objects/fileobject.c	(revision 58930)
+++ Objects/fileobject.c	(working copy)
@@ -325,7 +325,10 @@
 	return buf;
 }
 
-/* **************************** std printer **************************** */
+/* **************************** std printer ****************************
+ * The stdprinter is used during the boot strapping phase as a preliminary
+ * file like object for sys.stderr.
+ */
 
 typedef struct {
 	PyObject_HEAD
@@ -347,15 +350,24 @@
 	return (PyObject *) self;
 }
 
+static int
+fileio_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+	PyErr_SetString(PyExc_TypeError,
+			"cannot create 'stderrprinter' instances");
+	return -1;
+}
+
 PyObject *
 PyFile_NewStdPrinter(int fd)
 {
 	PyStdPrinter_Object *self;
-
-	if ((fd != fileno(stdout) && fd != fileno(stderr)) || fd < 0) {
+#ifndef PY_STDERR_FILE
+	if (fd != fileno(stdout) && fd != fileno(stderr)) {
 		/* not enough infrastructure for PyErr_BadInternalCall() */
 		return NULL;
 	}
+#endif
 
 	self = PyObject_New(PyStdPrinter_Object,
 			    &PyStdPrinter_Type);
@@ -372,14 +384,17 @@
 	Py_ssize_t n;
 
 	if (self->fd < 0) {
-		PyErr_SetString(PyExc_ValueError,
-				"I/O operation on closed file");
-		return NULL;
+		/* fd might be invalid on Windows
+		 * I can't raise an exception here. It may lead to an
+		 * unlimited recursion in the case stderr is invalid.
+		 */
+		return PyLong_FromLong((long)-1);
 	}
 
-	if (!PyArg_ParseTuple(args, "s#", &c, &n)) {
+	if (!PyArg_ParseTuple(args, "s", &c)) {
 		return NULL;
 	}
+	n = strlen(c);
 
 	Py_BEGIN_ALLOW_THREADS
 	errno = 0;
@@ -393,14 +408,75 @@
 		return NULL;
 	}
 
-	return PyInt_FromSsize_t(n);
+	return PyLong_FromSsize_t(n);
 }
 
+static PyObject *
+stdprinter_fileno(PyStdPrinter_Object *self)
+{
+	return PyInt_FromLong((long) self->fd);
+}
+
+static PyObject *
+stdprinter_repr(PyStdPrinter_Object *self)
+{
+	return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
+				    self->fd, self);
+}
+
+static PyObject *
+stdprinter_noop(PyStdPrinter_Object *self)
+{
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+stdprinter_isatty(PyStdPrinter_Object *self)
+{
+	long res;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = isatty(self->fd);
+	Py_END_ALLOW_THREADS
+
+	return PyBool_FromLong(res);
+}
+
 static PyMethodDef stdprinter_methods[] = {
-	{"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
- 	{NULL,		NULL}		/* sentinel */
+	{"close",	(PyCFunction)stdprinter_noop, METH_NOARGS, ""},
+	{"flush",	(PyCFunction)stdprinter_noop, METH_NOARGS, ""},
+	{"fileno",	(PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
+	{"isatty",	(PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
+	{"write",	(PyCFunction)stdprinter_write, METH_VARARGS, ""},
+	{NULL,		NULL}  /*sentinel */
 };
 
+static PyObject *
+get_closed(PyStdPrinter_Object *self, void *closure)
+{
+	Py_INCREF(Py_False);
+	return Py_False;
+}
+
+static PyObject *
+get_mode(PyStdPrinter_Object *self, void *closure)
+{
+	return PyUnicode_FromString("w");
+}
+
+static PyObject *
+get_encoding(PyStdPrinter_Object *self, void *closure)
+{
+	Py_RETURN_NONE;
+}
+
+static PyGetSetDef stdprinter_getsetlist[] = {
+	{"closed", (getter)get_closed, NULL, "True if the file is closed"},
+	{"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
+	{"mode", (getter)get_mode, NULL, "String giving the file mode"},
+	{0},
+};
+
 PyTypeObject PyStdPrinter_Type = {
 	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"stderrprinter",			/* tp_name */
@@ -412,7 +488,7 @@
 	0,					/* tp_getattr */
 	0,					/* tp_setattr */
 	0,					/* tp_compare */
-	0,					/* tp_repr */
+	(reprfunc)stdprinter_repr,		/* tp_repr */
 	0,					/* tp_as_number */
 	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
@@ -432,13 +508,13 @@
 	0,					/* tp_iternext */
 	stdprinter_methods,			/* tp_methods */
 	0,					/* tp_members */
-	0,					/* tp_getset */
+	stdprinter_getsetlist,			/* tp_getset */
 	0,					/* tp_base */
 	0,					/* tp_dict */
 	0,					/* tp_descr_get */
 	0,					/* tp_descr_set */
 	0,					/* tp_dictoffset */
-	0,					/* tp_init */
+	fileio_init,				/* tp_init */
 	PyType_GenericAlloc,			/* tp_alloc */
 	stdprinter_new,				/* tp_new */
 	PyObject_Del,				/* tp_free */
Index: PC/pyconfig.h
===================================================================
--- PC/pyconfig.h	(revision 58930)
+++ PC/pyconfig.h	(working copy)
@@ -706,4 +706,7 @@
    socket handles greater than FD_SETSIZE */
 #define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
 
+/* Redirect stderr and stdout to a file named stderr.txt */
+/* #define PY_STDERR_FILE 1 */
+
 #endif /* !Py_CONFIG_H */
Index: Python/pythonrun.c
===================================================================
--- Python/pythonrun.c	(revision 58930)
+++ Python/pythonrun.c	(working copy)
@@ -17,7 +17,6 @@
 #include "ast.h"
 #include "eval.h"
 #include "marshal.h"
-
 #ifdef HAVE_SIGNAL_H
 #include <signal.h>
 #endif
@@ -40,6 +39,10 @@
 				   _Py_GetRefTotal())
 #endif
 
+#ifdef PY_STDERR_FILE
+#include <fcntl.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -152,8 +155,11 @@
 {
 	PyInterpreterState *interp;
 	PyThreadState *tstate;
-	PyObject *bimod, *sysmod, *pstderr;
+	PyObject *bimod, *sysmod, *pstd;
 	char *p;
+#ifdef PY_STDERR_FILE
+	int fd;
+#endif
 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
 	char *codeset;
 #endif
@@ -231,12 +237,25 @@
 
 	/* Set up a preliminary stderr printer until we have enough
 	   infrastructure for the io module in place. */
-	pstderr = PyFile_NewStdPrinter(fileno(stderr));
-	if (pstderr == NULL)
+#ifdef PY_STDERR_FILE
+	fd = open("stderr.txt", O_WRONLY|O_BINARY|O_CREAT|O_TRUNC);
+	pstd = PyFile_NewStdPrinter(fd);
+#else
+	pstd = PyFile_NewStdPrinter(fileno(stderr));
+#endif
+	if (pstd == NULL)
 		Py_FatalError("Py_Initialize: can't set preliminary stderr");
-	PySys_SetObject("stderr", pstderr);
-	PySys_SetObject("__stderr__", pstderr);
+	PySys_SetObject("stderr", pstd);
+	PySys_SetObject("__stderr__", pstd);
 
+#ifndef PY_STDERR_FILE
+	pstd = PyFile_NewStdPrinter(fileno(stdout));
+#endif
+	if (pstd == NULL)
+		Py_FatalError("Py_Initialize: can't set preliminary stdout");
+	PySys_SetObject("stdout", pstd);
+	PySys_SetObject("__stdout__", pstd);
+
 	_PyImport_Init();
 
 	/* initialize builtin exceptions */
@@ -756,6 +775,7 @@
 	PySys_SetObject("stdin", std);
 	Py_DECREF(std);
 
+#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
 	/* Set sys.stdout */
 	if (!(std = PyFile_FromFd(fileno(stdout), "<stdout>", "w", -1,
 				  NULL, "\n", 0))) {
@@ -765,7 +785,6 @@
 	PySys_SetObject("stdout", std);
 	Py_DECREF(std);
 
-#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
 	/* Set sys.stderr, replaces the preliminary stderr */
 	if (!(std = PyFile_FromFd(fileno(stderr), "<stderr>", "w", -1,
 				  NULL, "\n", 0))) {
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to