add an indent to a stream

Manuel M Garcia mail at manuelmgarcia.com
Sun Mar 9 23:57:19 EST 2003


I often need to add an indent to a stream, usually so the output of
pprint or traceback is indented so I can tell debugging output from my
program's actual output.

Below is a class to help do this.  I think I got the details right.
The 'print' statement, when used with commas, is more complicated than
I thought.

What is the exact rule for when the 'print' command inserts a space
because of a comma?  I guess it has something to do with the attribute
'softspace'.

I played around with the code from Alex Martelli's explination of
'softspace'

http://groups.google.com/groups?as_umsgid=nXqA8.92311%24vF6.2766580@news2.tin.it

It looks like 'softspace' is strictly to help 'print', it really can't
help me know when I am at the beginning of a line, because the 'print'
statement set it at the 'wrong' time.

Manuel

# ################## #
# indentstream.py

import sys

class IndentStream:
    """Stream with indent at start of each line.
    
    Indent can be a string or
    the number of spaces you wish to indent.

    """
    
    def __init__(self, indent='    ', stream=None):
        if stream is None:
            self._stream = sys.stdout
        else:
            self._stream = stream
        try:
            indent = ' ' * indent
        except TypeError:
            pass
        self._indent = indent
        self._nl_indent = '\n' + indent
        self._indent_size = len(indent)
        self._comma = 0
        self.softspace = 0
        
    def write(self, s):
        comma = not s.endswith('\n')
        s = s.replace('\n', self._nl_indent)
        if not self._comma: s = self._indent + s
        if s.endswith(self._nl_indent): s = s[:-self._indent_size]
        self._stream.write(s)
        self._comma = comma

if __name__ == '__main__':
    
    print 'hello'
    print 'hello2'
    print
    print 'hello again'
    print 'comma', 'comma',
    print
    print 'comma2','comma2',
    print
    print 'goodbye'
    print 'fiddle',
    print '',
    print 'sticks',
    print '!'
    print 'crumbs',
    print 'with nl\n',
    print 'crumbs'
    print 'goodbye again',
    print '\n',
    print 'goodbye again2'
    
    _indentstream = IndentStream(4)
    
    print >> _indentstream, 'hello'
    print >> _indentstream, 'hello2'
    print >> _indentstream
    print >> _indentstream, 'hello again'
    print >> _indentstream, 'comma', 'comma',
    print >> _indentstream
    print >> _indentstream, 'comma2','comma2',
    print >> _indentstream
    print >> _indentstream, 'goodbye'
    print >> _indentstream, 'fiddle',
    print >> _indentstream, '',
    print >> _indentstream, 'sticks',
    print >> _indentstream, '!'
    print >> _indentstream, 'crumbs',
    print >> _indentstream, 'with nl\n',
    print >> _indentstream, 'crumbs'
    print >> _indentstream, 'goodbye again',
    print >> _indentstream, '\n',
    print >> _indentstream, 'goodbye again2'

    import inspect
    import pprint
    import StringIO
    import tokenize
    import token

    _readline = StringIO.StringIO(
        inspect.getsource(inspect.getsource)).readline
    _pprint = pprint.PrettyPrinter(
        indent=4,
        stream=IndentStream('??????? ')).pprint
    def _(x):
        t = list(x[:4])
        t[0] = token.tok_name[t[0]]
        if t[0] == 'STRING': t[1] = t[1].split('\n')
        return tuple(t)
    _pprint([ _(x) for x in tokenize.generate_tokens(_readline) ])





More information about the Python-list mailing list