are final newlines appended if output lacks it?

Bengt Richter bokr at oz.net
Sun May 4 02:35:49 EDT 2003


On Sat, 03 May 2003 23:59:14 -0400, Tim Peters <tim.one at comcast.net> wrote:

>[Dan Jacobson]
>> Doing help() print explains how the blank got in here,
>>
>> $ python -c "print 'wow',;print 'pow',"|od -c
>> 0000000   w   o   w       p   o   w  \n
>> 0000010
>>
>> But not the newline. Why?
>
>[John Machin]
>> derrrrr ..... my brain was in neutral. Dan's question/problem is quite
>> valid, not explained by the documentation, and I have been able to
>> reproduce it on Windows 2000 with Python 2.2.2.
>>
>> Doing this give the same effect as what Dan got, except that of course
>> with Windows the offending extra is '\r\n' instead of just '\n':
>>
>> python -c "print 'wow',;print 'pow'," >powwow.txt
>>
>> Doing this:
>>
>> python -c "import sys;sys.stdout.write('abc');sys.stdout.write('xyz')"
>>           > abcxyz.txt
>>
>> produces no newline.  Looks like there's an undocumented "feature" of
>> the Python's print statement, nothing to do with the C stdio library
>> or the OS.
>
>OTOH, you'll find that
>
>    python -c "print 'abc\n',"
>
>produces 4 (on Linux) or 5 (on Windows) characters.  It has to do with
>whether sys.stdout.softspace is set when the program is done.
>PyRun_SimpleFileExFlags() ends with
>
>	if (Py_FlushLine())
>		PyErr_Clear();
>	return 0;
>
>and Py_FlushLine() is
>
>int
>Py_FlushLine(void)
>{
>	PyObject *f = PySys_GetObject("stdout");
>	if (f == NULL)
>		return 0;
>	if (!PyFile_SoftSpace(f, 0))
>		return 0;
>	return PyFile_WriteString("\n", f);
>}
>
>So it's specifically sys.stdout (and only sys.stdout) that may get a newline
>tacked on, and the relation to print is that normally only print fiddles
>with a file's softspace attribute.
>
>Code would break if we changed this, so learn to love it <wink>.  I expect
>that in Python 3, there won't be any softspace gimmick.
>
>
So is the goal is to guarantee a final EOL if the last output to sys.stdout
was from a print? (Apparently sys.stdout.write() resets sys.stdout.softspace
unconditionally, so it's allowed to have the last word with no tack-ons,
but a final print with a trailing comma will get its softspace turned to an EOL?

I guess this is just policy, and not related to the apparent (IMO) bug that
confuses interactive echo with program output to stdout, so that interactive
echo of a typed line end erroneously (IMO) resets sys.stdout.softspace. Note:

 >>> import sys
 >>> class SO:
 ...     def write(self,s): sys.stderr.write(`s`+'\n')
 ...
 >>> sys.stdout = SO()
 >>> print sys.stdout.softspace,; print sys.stdout.softspace,
 '0'
 ' '
 '1'
 '\n'
 >>> print sys.stdout.softspace,; print sys.stdout.softspace,
 '0'
 ' '
 '1'
 '\n'
 >>> def foo():
 ...     print sys.stdout.softspace,; print sys.stdout.softspace,
 ...     print sys.stdout.softspace,; print sys.stdout.softspace,
 ...
 >>> foo()
 '0'
 ' '
 '1'
 ' '
 '1'
 ' '
 '1'
 '\n'
 
Note that the interactive call to foo() only echoed one EOL, so the
softspace from the first print line survived to influence the second line
inside foo, unlike for the separate invocations preceding.

If the interactive _echo_ is actually going to sys.__stdout__ when normal
sys.stdout is redirected, perhaps sys.__stdout__.softspace should be reset
for the interactive EOL echo instead of sys.stdout.softspace?

Regards,
Bengt Richter




More information about the Python-list mailing list