only avoids wait states for transfer calls and does not address the data producer’s
failure to send buffered output.
Stream requirements
To make some of this more concrete, Example 12-12 illustrates how some of these
complexities apply to redirected standard streams, by attempting to connect them to
both text and binary mode files produced by open and accessing them with print and
input built-ins much as redirected script might.
Example 12-12. PP4E\Internet\Sockets\test-stream-modes.py
"""
test effect of connecting standard streams to text and binary mode files
same holds true for socket.makefile: print requires text mode, but text
mode precludes unbuffered mode -- use -u or sys.stdout.flush() calls
"""
import sys
def reader(F):
tmp, sys.stdin = sys.stdin, F
line = input()
print(line)
sys.stdin = tmp
reader( open('test-stream-modes.py') ) # works: input() returns text
reader( open('test-stream-modes.py', 'rb') ) # works: but input() returns bytes
def writer(F):
tmp, sys.stdout = sys.stdout, F
print(99, 'spam')
sys.stdout = tmp
writer( open('temp', 'w') ) # works: print() passes text str to .write()
print(open('temp').read())
writer( open('temp', 'wb') ) # FAILS on print: binary mode requires bytes
writer( open('temp', 'w', 0) ) # FAILS on open: text must be unbuffered
When run, the last two lines in this script both fail—the second to last fails because
print passes text strings to a binary-mode file (never allowed for files in general), and
the last fails because we cannot open text-mode files in unbuffered mode in Python 3.X
(text mode implies Unicode encodings). Here are the errors we get when this script is
run: the first run uses the script as shown, and the second shows what happens if the
second to last line is commented out (I edited the exception text slightly for
presentation):
C:\...\PP4E\Internet\Sockets> test-stream-modes.py
"""
b'"""\r'
99 spam
834 | Chapter 12: Network Scripting