pretty printing for everyone!

April 25th, 2010

I've been toying with the idea of trying my hand a generic pretty printer module for a while. Lately I've had to deal with cyclic object graphs and things like that, where having a dump of the data is pretty handy. Granted there is a pprint module in the standard library. But what it does is format and print iterables (lists, dicts, tuples..), it doesn't attempt to show you the contents of an object. Of course, when you're messing with objects this is very useful to have.

So I thought that I would build a recursive iterable that I can give to pprint. Here's an example:

class Node(object):
    classatt = 'hidden'
    def __init__(self, name):
        self.name = name

a, b, c, d = Node('A'), Node('B'), Node('C'), Node('D')
a.refs = [b, d]
b.refs = [c]
c.refs = [a]
d.refs = [c]

This will give you:

{'__type__': '<Node {id0}>',
 'name': "'A'",
 'refs': [{'__type__': '<Node {id1}>',
           'name': "'B'",
           'refs': [{'__type__': '<Node {id2}>',
                     'name': "'C'",
                     'refs': ['dup <Node {id0}>']}]},
          {'__type__': '<Node {id3}>',
           'name': "'D'",
           'refs': [{'__type__': '<Node {id2}>',
                     'name': "'C'",
                     'refs': ['dup <Node {id0}>']}]}]}

There are two things being shown here:

  • node C is reachable through ABC and ADC.
  • A takes part in two cycles: ABCA and ADCA.

It would be nice to have a way to see this from the output. So aside from the object attributes themselves there is also a __type__ attribute which tells you the type that you're looking at. And it has a marker of the form {id1}, where id1 is an identifier for this object, so that you can see where it pops up in a different part of the graph.

Now, suppose we follow A to B to C and then to A. We are now seeing A for the second time. Instead of printing the object again we print a duplicate marker: dup <Node {id0}>. The identifier is supposed to be vim * friendly, so if you pipe the output to vim, put the cursor over it and hit * (also might want to do set hlsearch) then you'll see it light up all the other instances of it in the graph.

pretty_printing_gvim

Well, that's all for now. It's definitely not the last word in pretty printing, but it's useful already.

I thought maybe github's gists would be appropriate for something like this:

:: random entries in this category ::

1 Responses to "pretty printing for everyone!"

  1. [...] of their own into a new github repository, appropriately named “pybits”. It holds the pretty printer and this rewritten ansicolor module, and it’ll probably grow with the [...]