This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Creideiki
Recipients Creideiki, pitrou
Date 2017-12-20.11:09:59
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1513768199.13.0.213398074469.issue32345@psf.upfronthosting.co.za>
In-reply-to
Content
Hmm. Yes and no; you seem to be correct in that the problem is on the libc level, but Python definitely does something special.

By the way, this is glibc 2.26.

I tried this C program:

#include <stdio.h>
#include <unistd.h>

int main()
{
   usleep(5 * 1000 * 1000);
   fwrite("A", 1, 1, stdout);
   perror("A");
   fwrite("\n", 1, 1, stdout);
   perror("newline 1");
   fwrite("B\nC", 3, 1, stdout);
   perror("BC");
   fwrite("\n", 1, 1, stdout);
   perror("newline 2");
   fwrite("D", 1, 1, stdout);
   perror("D");
   fwrite("\n", 1, 1, stdout);
   perror("newline 3");
   return 0;
}

Which behaves similarly when there's a newline in the middle of the string, in that fwrite() returns with an error after writing the newline:

write(3, "A: Success\n", 11)            = -1 EIO (Input/output error)
write(1, "A\n", 2)                      = -1 EIO (Input/output error)
write(3, "newline 1: Input/output error\n", 30) = -1 EIO (Input/output error)
write(1, "B\n", 2)                      = -1 EIO (Input/output error)
write(3, "BC: Input/output error\n", 23) = -1 EIO (Input/output error)
write(1, "\n", 1)                       = -1 EIO (Input/output error)
write(3, "newline 2: Input/output error\n", 30) = -1 EIO (Input/output error)
write(3, "D: Input/output error\n", 22) = -1 EIO (Input/output error)
write(1, "D\n", 2)                      = -1 EIO (Input/output error)
write(3, "newline 3: Input/output error\n", 30) = -1 EIO (Input/output error)

However, as can be seen from the result of the perror() calls, every fwrite() after the first buffer flush (which happens on newlines, since stdout to a terminal is line buffered) fails with EIO. This should mean that, at the latest, the second Python print() call should fail. But it doesn't:

#!/bin/env python2.7
import time
time.sleep(5)
print('A')
print('E')
print('B\nC')
print('D')

write(1, "A\n", 2)                      = -1 EIO (Input/output error)
write(1, "E\n", 2)                      = -1 EIO (Input/output error)
write(1, "B\n", 2)                      = -1 EIO (Input/output error)
write(2, "Traceback (most recent call last):\n", 35) = -1 EIO (Input/output error)
write(2, "  File \"./fatal.py\", line 6, in <module>\n", 41) = -1 EIO (Input/output error)

So Python does make a difference between the implicit newline added to the end of each print() and a newline in the middle of the user-supplied string.
History
Date User Action Args
2017-12-20 11:09:59Creideikisetrecipients: + Creideiki, pitrou
2017-12-20 11:09:59Creideikisetmessageid: <1513768199.13.0.213398074469.issue32345@psf.upfronthosting.co.za>
2017-12-20 11:09:59Creideikilinkissue32345 messages
2017-12-20 11:09:59Creideikicreate