Author snaphat
Recipients eryksun, r.david.murray, snaphat, steve.dower, tim.golden, zach.ware
Date 2014-10-19.23:07:33
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1413760054.04.0.243085930028.issue22673@psf.upfronthosting.co.za>
In-reply-to
Content
Yeah, it is windows specific. The problem is that if you open conout$ and the descriptor isn't 1, the buffer doesn't flush normally so the console won't display anything unless you manually flush it.

Now, why would you want to redirect STDOUT to the console in the first place like this? It's in the case where AllocConsole() has been called and since the console is new, STDOUT is directed elsewhere or nowhere. So you can't dup it or restore it or anything like that. In order, to get the normal behavior for the windows console the redirect is needed for STDOUT with fileno=1. But, as far as I can tell, it is impossible to actually do the redirect in python.

Anyway, let me discuss a bit the behavior between C, Python, and Perl w.r.t. to opening files. It'll help clarify where python is lacking in comparison to perl and c. You basically have two different 'flavors' of prototypes between the languages:
1) handle fd = open(filename, mode)
2) open(filename, mode, fd)

In C, the first prototype matches 'fopen' and is used to open a file. And the second prototype matches 'freopen' and is used to associate a different file with the an existing file descriptor. Moreover, you can't use stdout as an lvalue so you simply can't redefine it.

In code terms:
   stdout = fopen("CONOUT$", "w"); //Invalid lvalue
   FILE* file= fopen("CONOUT$", "w"); // Valid fileno=3 to N.
   freopen("CONOUT$", "w", stdout); // Valid fileno=1.
   freopen("CONOUT$", "w", file); //Valid IFF fd!=0, the value of fd is whatever it was previously.

In perl the open function is similar to the second prototype mentioned above, but the parameters are backwards. Moreover, It can either be used for new file descriptors or for reusing file descriptors unlike C's version of the second prototype.

In code terms:
   open (STDOUT, ">", "CONOUT$"); //Valid fileno=1. Reuses the desciptor number.
   open (FILE, ">", "CONOUT$"); //Valid fileno=3 to N. Reuses the fileno if a valid descriptor. Otherwise, creates a new one. 


In python, the os.open function matches the first prototype with the exception that it can be used to redirect stdout unlike C's version.

In code terms:
   sys.stdout = os.open("CONOUT$", "w"); // Valid fileno=3 to N.

So when you look at the behavior, you'll note that both C and Perl allow you to redirect using an existing descriptor; where as, Python seems to be unable to do this. Normally, it doesn't matter since you can just save stdout ahead of time, but it matters in the case where you don't start with a console (pythonw), or deallocated the console and allocated a new one later on.

As it stands, I don't believe this is fixable without an API extension/change of some sort that would allow passing filehandles... either that or... just making $CONOUT always allocate to 1 regardless. Though the latter would change the behavior for anyone who currently uses CONOUT$ in that it currently needs to be manually flushed to display to the console; where as, it wouldn't with the change.

Boy that is long winded, but hopefully it describes the issue adequately.
History
Date User Action Args
2014-10-19 23:07:34snaphatsetrecipients: + snaphat, tim.golden, r.david.murray, zach.ware, eryksun, steve.dower
2014-10-19 23:07:34snaphatsetmessageid: <1413760054.04.0.243085930028.issue22673@psf.upfronthosting.co.za>
2014-10-19 23:07:34snaphatlinkissue22673 messages
2014-10-19 23:07:33snaphatcreate