PEP 259: Omit printing newline after newline
This commit is contained in:
parent
afd299ae13
commit
559c1c1ad4
|
@ -60,6 +60,7 @@ Index by Category
|
|||
S 256 pep-0256.txt Docstring Processing System Framework Goodger
|
||||
S 257 pep-0257.txt Docstring Conventions Goodger
|
||||
S 258 pep-0258.txt DPS Generic Implementation Details Goodger
|
||||
S 259 pep-0259.txt Omit printing newline after newline van Rossum
|
||||
|
||||
Py-in-the-sky PEPs (not ready; may become active yet)
|
||||
|
||||
|
@ -184,6 +185,7 @@ Numerical Index
|
|||
S 256 pep-0256.txt Docstring Processing System Framework Goodger
|
||||
S 257 pep-0257.txt Docstring Conventions Goodger
|
||||
S 258 pep-0258.txt DPS Generic Implementation Details Goodger
|
||||
S 259 pep-0259.txt Omit printing newline after newline van Rossum
|
||||
|
||||
|
||||
Key
|
||||
|
|
87
pep-0253.txt
87
pep-0253.txt
|
@ -34,19 +34,24 @@ Abstract
|
|||
sufficiently familiar with the traditional way of creating new
|
||||
Python types in C.
|
||||
|
||||
This PEP will introduce the following optional features to types:
|
||||
This PEP will introduce the following features:
|
||||
|
||||
- create an instance of a type by calling it
|
||||
- a type, like a class, can be a factory for its instances
|
||||
|
||||
- create a subtype in C by specifying a base type pointer
|
||||
- types can be subtyped in C by specifying a base type pointer
|
||||
|
||||
- create a subtype in Python using a class statement
|
||||
- types can be subtyped in Python using the class statement
|
||||
|
||||
- multiple inheritance
|
||||
- multiple inheritance from types (insofar as practical)
|
||||
|
||||
This PEP builds on PEP 252, which adds standard introspection to
|
||||
- the standard coercions (int, tuple, str etc.) will be the
|
||||
corresponding type objects
|
||||
|
||||
- a standard type hierarchy
|
||||
|
||||
This PEP builds on pep-0252, which adds standard introspection to
|
||||
types; in particular, types are assumed to have e.g. a __hash__
|
||||
method when the type object defines the tp_hash slot. PEP 252 also
|
||||
method when the type object defines the tp_hash slot. pep-0252 also
|
||||
adds a dictionary to type objects which contains all methods. At
|
||||
the Python level, this dictionary is read-only; at the C level, it
|
||||
is accessible directly (but modifying it is not recommended except
|
||||
|
@ -76,12 +81,13 @@ Metatypes
|
|||
"Don Beaudry hook", which says that if a metatype is callable, its
|
||||
instances (which are regular types) can be subclassed (really
|
||||
subtyped) using a Python class statement. We will use this rule
|
||||
to support subtyping of built-in types, and in the process we will
|
||||
introduce some additional metatypes, and a "metametatype". (The
|
||||
metametatype is nothing unusual; Python's type system allows any
|
||||
number of metalevels.)
|
||||
to support subtyping of built-in types, and in fact it greatly
|
||||
simplifies the logic of class creation to always simply call the
|
||||
metatype. When no base class is specified, a default metatype is
|
||||
called -- the default metatype is the "ClassType" object, so the
|
||||
class statement will behave as before in the normal case.
|
||||
|
||||
Note that Python uses the concept of metatypes or metaclasses in a
|
||||
Python uses the concept of metatypes or metaclasses in a
|
||||
different way than Smalltalk. In Smalltalk-80, there is a
|
||||
hierarchy of metaclasses that mirrors the hierarchy of regular
|
||||
classes, metaclasses map 1-1 to classes (except for some funny
|
||||
|
@ -104,7 +110,8 @@ Metatypes
|
|||
Instantiation by calling the type object
|
||||
|
||||
Traditionally, for each type there is at least one C function that
|
||||
creates instances of the type. This function has to take care of
|
||||
creates instances of the type (e.g. PyInt_FromLong(),
|
||||
PyTuple_New() and so on). This function has to take care of
|
||||
both allocating memory for the object and initializing that
|
||||
memory. As of Python 2.0, it also has to interface with the
|
||||
garbage collection subsystem, if the type chooses to participate
|
||||
|
@ -127,24 +134,17 @@ Instantiation by calling the type object
|
|||
can't be called. Now we're adding a tp_call slot to the metatype,
|
||||
which makes all types "callable" in a trivial sense. But
|
||||
obviously the metatype's tp_call implementation doesn't know how
|
||||
to initialize individual types. So the type defines a new slot,
|
||||
tp_construct, which is invoked by the metatype's tp_call slot. If
|
||||
the tp_construct slot is NULL, the metatype's tp_call issues a
|
||||
nice error message: the type isn't callable.
|
||||
to initialize the instances of individual types. So the type
|
||||
defines a new slot, tp_new, which is invoked by the metatype's
|
||||
tp_call slot. If the tp_new slot is NULL, the metatype's tp_call
|
||||
issues a nice error message: the type isn't callable.
|
||||
|
||||
We already know that tp_construct is responsible for initializing
|
||||
the object (this will be important for subtyping too). Who should
|
||||
be responsible for allocation of the new object? Either the
|
||||
metatype's tp_call can allocate the object, or the type's
|
||||
tp_construct can allocate it. The solution is copied from typical
|
||||
C++ implementations: if the metatype's tp_call allocates storage
|
||||
for the object it passes the storage as a pointer to the type's
|
||||
tp_construct; if the metatype's tp_call does not allocate storage,
|
||||
it passes a NULL pointer to the type's tp_call in which case the
|
||||
type allocates the storage itself. This moves the policy decision
|
||||
to the metatype, and different metatypes may have different
|
||||
policies. The mechanisms are fixed though: either the metatype's
|
||||
tp_call allocates storage, or the type's tp_construct allocates.
|
||||
This mechanism gives the maximum freedom to the type: a type's
|
||||
tp_new doesn't necessarily have to return a new object, or even an
|
||||
object that is an instance of the type (although the latter should
|
||||
be rare).
|
||||
|
||||
HIRO
|
||||
|
||||
The deallocation mechanism chosen should match the allocation
|
||||
mechanism: an allocation policy should prescribe both the
|
||||
|
@ -279,7 +279,7 @@ Subtyping in C
|
|||
PyType_InitDict() must be called. This replaces zero slots in the
|
||||
subtype with the value of the corresponding base type slots. It
|
||||
also fills in tp_dict, the type's dictionary; this is more a
|
||||
matter of PEP 252.
|
||||
matter of pep-0252.
|
||||
|
||||
The subtype's tp_dealloc slot deserves special attention. It must
|
||||
uninitialize and deallocate the object in an orderly manner: first
|
||||
|
@ -329,7 +329,7 @@ Subtyping in Python
|
|||
Assume B is a type object. Since type objects are objects, and
|
||||
every object has a type, B has a type. B's type is accessible via
|
||||
type(B) or B.__class__ (the latter notation is new for types; it
|
||||
is introduced in PEP 252). Let's say B's type is M (for
|
||||
is introduced in pep-0252). Let's say B's type is M (for
|
||||
Metatype). The class statement will create a new type, C. Since
|
||||
C will be a type object just like B, we view the creation of C as
|
||||
an instantiation of the metatype, M. The information that needs
|
||||
|
@ -373,6 +373,29 @@ Subtyping in Python
|
|||
dictionary (the third argument to the call to M).
|
||||
|
||||
|
||||
Implementation
|
||||
|
||||
A prototype implementation of this PEP is available from CVS as a
|
||||
branch named "descr-branch". To experiment with this
|
||||
implementation, proceed to check out Python from CVS according to
|
||||
the instructions at http://sourceforge.net/cvs/?group_id=5470 but
|
||||
add the arguments "-r descr-branch" to the cvs checkout command.
|
||||
(You can also start with an existing checkout and do "cvs update
|
||||
-r descr-branch".) For some examples of the features described
|
||||
here, see the file Lib/test/test_descr.py and the extension module
|
||||
Modules/spam.c.
|
||||
|
||||
Note: the code in this branch is for pep-0252, pep-0253, and
|
||||
pep-254.
|
||||
|
||||
|
||||
References
|
||||
|
||||
[1] "Putting Metaclasses to Work", by Ira R. Forman and Scott
|
||||
H. Danforth, Addison-Wesley 1999.
|
||||
(http://www.aw.com/product/0,2627,0201433052,00.html)
|
||||
|
||||
|
||||
Copyright
|
||||
|
||||
This document has been placed in the public domain.
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
PEP: 259
|
||||
Title: Omit printing newline after newline
|
||||
Version: $Revision$
|
||||
Author: guido@python.org (Guido van Rossum)
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Python-Version: 2.2
|
||||
Created: 11-Jun-2001
|
||||
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
|
||||
|
||||
|
||||
Copyright
|
||||
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
Loading…
Reference in New Issue