forked from python/peps
-
Notifications
You must be signed in to change notification settings - Fork 2
/
pep-0259.txt
144 lines (98 loc) · 3.69 KB
/
pep-0259.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
PEP: 259
Title: Omit printing newline after newline
Version: $Revision$
Last-Modified: $Date$
Author: guido@python.org (Guido van Rossum)
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.
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
End: