136 lines
3.6 KiB
Plaintext
136 lines
3.6 KiB
Plaintext
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.
|