PEP: 259 Title: Omit printing newline after newline Author: Guido van
Rossum <guido@python.org> Status: Rejected Type: Standards Track
Content-Type: text/x-rst Created: 11-Jun-2001 Python-Version: 2.2
Post-History: 11-Jun-2001

Abstract

Currently, the print statement always appends a newline, unless a
trailing comma is used. This means that if we want to print data that
already ends in a newline, we get two newlines, unless special
precautions are taken.

I propose to skip printing the newline when it follows a newline that
came from data.

In order to avoid having to add yet another magic variable to file
objects, I propose to give the existing 'softspace' variable an extra
meaning: a negative value will mean "the last data written ended in a
newline so no space or newline is required."

Problem

When printing data that resembles the lines read from a file using a
simple loop, double-spacing occurs unless special care is taken:

    >>> for line in open("/etc/passwd").readlines():
    ... print line
    ...
    root:x:0:0:root:/root:/bin/bash

    bin:x:1:1:bin:/bin:

    daemon:x:2:2:daemon:/sbin:

    (etc.)

    >>>

While there are easy work-arounds, this is often noticed only during
testing and requires an extra edit-test roundtrip; the fixed code is
uglier and harder to maintain.

Proposed Solution

In the PRINT_ITEM opcode in ceval.c, when a string object is printed, a
check is already made that looks at the last character of that string.
Currently, if that last character is a whitespace character other than
space, the softspace flag is reset to zero; this suppresses the space
between two items if the first item is a string ending in newline, tab,
etc. (but not when it ends in a space). Otherwise the softspace flag is
set to one.

The proposal changes this test slightly so that softspace is set to:

-   -1 -- if the last object written is a string ending in a newline
-   0 -- if the last object written is a string ending in a whitespace
    character that's neither space nor newline
-   1 -- in all other cases (including the case when the last object
    written is an empty string or not a string)

Then, the PRINT_NEWLINE opcode, printing of the newline is suppressed if
the value of softspace is negative; in any case the softspace flag is
reset to zero.

Scope

This only affects printing of 8-bit strings. It doesn't affect Unicode,
although that could be considered a bug in the Unicode implementation.
It doesn't affect other objects whose string representation happens to
end in a newline character.

Risks

This change breaks some existing code. For example:

    print "Subject: PEP 259\n"
    print message_body

In current Python, this produces a blank line separating the subject
from the message body; with the proposed change, the body begins
immediately below the subject. This is not very robust code anyway; it
is better written as:

    print "Subject: PEP 259"
    print
    print message_body

In the test suite, only test_StringIO (which explicitly tests for this
feature) breaks.

Implementation

A patch relative to current CVS is here:

    http://sourceforge.net/tracker/index.php?func=detail&aid=432183&group_id=5470&atid=305470

Rejected

The user community unanimously rejected this, so I won't pursue this
idea any further. Frequently heard arguments against included:

-   It is likely to break thousands of CGI scripts.
-   Enough magic already (also: no more tinkering with 'print' please).

Copyright

This document has been placed in the public domain.