[Python-Dev] PEP 214, extended print statement

Barry A. Warsaw bwarsaw@beopen.com
Wed, 16 Aug 2000 11:11:57 -0400 (EDT)


After channeling and encouragement by Tim Peters, I've updated PEP
214, the extended print statement.  Text is included below, but is
also available at

    http://python.sourceforge.net/peps/pep-0214.html

SourceForge patch #100970 contains the patch to apply against the
current CVS tree if you want to play with it

    http://sourceforge.net/patch/download.php?id=100970

-Barry

-------------------- snip snip --------------------
PEP: 214
Title: Extended Print Statement
Version: $Revision: 1.3 $
Author: bwarsaw@beopen.com (Barry A. Warsaw)
Python-Version: 2.0
Status: Draft
Created: 24-Jul-2000
Post-History: 16-Aug-2000


Introduction

    This PEP describes a syntax to extend the standard `print'
    statement so that it can be used to print to any file-like object,
    instead of the default sys.stdout.  This PEP tracks the status and
    ownership of this feature.  It contains a description of the
    feature and outlines changes necessary to support the feature.
    This PEP summarizes discussions held in mailing list forums, and
    provides URLs for further information, where appropriate.  The CVS
    revision history of this file contains the definitive historical
    record.


Proposal

    This proposal introduces a syntax extension to the print
    statement, which allows the programmer to optionally specify the
    output file target.  An example usage is as follows:

        print >> mylogfile, 'this message goes to my log file'

    Formally, the syntax of the extended print statement is
    
        print_stmt: ... | '>>' test [ (',' test)+ [','] ] )

    where the ellipsis indicates the original print_stmt syntax
    unchanged.  In the extended form, the expression just after >>
    must yield an object with a write() method (i.e. a file-like
    object).  Thus these two statements are equivalent:

	print 'hello world'
        print >> sys.stdout, 'hello world'

    As are these two statements:

        print
        print >> sys.stdout

    These two statements are syntax errors:

        print ,
        print >> sys.stdout,


Justification

    `print' is a Python keyword and introduces the print statement as
    described in section 6.6 of the language reference manual[1].
    The print statement has a number of features:

    - it auto-converts the items to strings
    - it inserts spaces between items automatically
    - it appends a newline unless the statement ends in a comma

    The formatting that the print statement performs is limited; for
    more control over the output, a combination of sys.stdout.write(),
    and string interpolation can be used.

    The print statement by definition outputs to sys.stdout.  More
    specifically, sys.stdout must be a file-like object with a write()
    method, but it can be rebound to redirect output to files other
    than specifically standard output.  A typical idiom is

        sys.stdout = mylogfile
	try:
	    print 'this message goes to my log file'
	finally:
	    sys.stdout = sys.__stdout__

    The problem with this approach is that the binding is global, and
    so affects every statement inside the try: clause.  For example,
    if we added a call to a function that actually did want to print
    to stdout, this output too would get redirected to the logfile.

    This approach is also very inconvenient for interleaving prints to
    various output streams, and complicates coding in the face of
    legitimate try/except or try/finally clauses.


Reference Implementation

    A reference implementation, in the form of a patch against the
    Python 2.0 source tree, is available on SourceForge's patch
    manager[2].  This approach adds two new opcodes, PRINT_ITEM_TO and
    PRINT_NEWLINE_TO, which simply pop the file like object off the
    top of the stack and use it instead of sys.stdout as the output
    stream.


Alternative Approaches

    An alternative to this syntax change has been proposed (originally
    by Moshe Zadka) which requires no syntax changes to Python.  A
    writeln() function could be provided (possibly as a builtin), that
    would act much like extended print, with a few additional
    features.

	def writeln(*args, **kws):
	    import sys
	    file = sys.stdout
	    sep = ' '
	    end = '\n'
	    if kws.has_key('file'):
		file = kws['file']
		del kws['file']
	    if kws.has_key('nl'):
		if not kws['nl']:
		    end = ' '
		del kws['nl']
	    if kws.has_key('sep'):
		sep = kws['sep']
		del kws['sep']
	    if kws:
		raise TypeError('unexpected keywords')
	    file.write(sep.join(map(str, args)) + end)

    writeln() takes a three optional keyword arguments.  In the
    context of this proposal, the relevant argument is `file' which
    can be set to a file-like object with a write() method.  Thus

        print >> mylogfile, 'this goes to my log file'

    would be written as

        writeln('this goes to my log file', file=mylogfile)

    writeln() has the additional functionality that the keyword
    argument `nl' is a flag specifying whether to append a newline or
    not, and an argument `sep' which specifies the separator to output
    in between each item.


References

    [1] http://www.python.org/doc/current/ref/print.html
    [2] http://sourceforge.net/patch/download.php?id=100970