show / README.rst

Simple, effective debug printing.

Logging, assertions, unit tests, and interactive debuggers are all great development tools. But sometimes you just need to print values as a program runs to see what's going on. Every language has features to print text, but they're not really customized for printing debugging information. show is. It provides a simple, DRY mechanism to "show what's going on."

Usage

from show import show

x = 12
nums = list(range(4))

show(x, nums)

yields:

x: 12  nums: [0, 1, 2, 3]

Debug Printing

Sometimes programs print so that users can see things, and sometimes they print so that develpopers can. show() is for developers, helping rapidly print the current state of variables. It replaces require the craptastic repetitiveness of:

print "x: {0}".format(x)

with:

show(x)

If you'd like to see where the data is being produced,:

show.set(where=True)

will turn on location reporting. This can also be set on call-by-call basis. show is built atop the options module for configuration management, and also the output management of say. All say options work in show. If you show() a literal string, it will be iterpolated as it would be in say:

show("{n} iterations, still running")

yields something like:

14312 iterations, still running

While:

s = '{n} iterations'
show(s)

yields:

s: '{n} iterations'

See say say for additional detail on its operation.

Turning Show On and Off

Often it's convenient to only display debugging information under some conditions, such as when a debug flag is set. That often leads to multi-line conditionals such as:

if debug:
    print "x:", x, "y:", y, "z:", z

With show it's a bit easier. There's a keyword argument, also called show, that controls whether anything is shown. Set it to True or False to show or not show, or set it to the debug flag:

show(x, y, z, show=debug)

Showing Collections

The goal of show is to provide the most useful information possible, in the quickest and simplest way. Not requiring programmers to explicitly restate values and names in print statements is the start, but the module also provides some additional functions that provide a bit more semantic value. For example, say.items() is designed to make printing collections easy. It shows not just the values, but also the cardinality (i.e., length) of the collection:

nums = list(range(4))
show.items(nums)

yields:

nums (4 items): [0, 1, 2, 3]

Showing Object Properties

show.props(x)

shows the properties of object x. ("Properties" here is generic language for "values" or "attributes" associated with an object, and isn't used in the technical sense of Python properties.) Properties will be listed alphabetically, but with those starting with underscores (_), usually indicating "private" data, sorted after those that are conventionally considered public.

If x has real @property members, those too displayed. However, other class attributes that x rightfully inherits, but that are not directly present in the x instance, will not be displayed.

An optional second parameter can determine which properties are shown. E.g.:

show.props(x, 'name,age')

Or if you prefer the keyword syntax, this is equivalent to:

show(x, props='name,age')

Or if you'd like all properties except a few:

show.props(x, omit='description,blurb')

Changing How Things Are Shown

By default, show uses Python's repr() function to format values. You may prefer some other kind of representation or formatting, however. For example, the pprint module pretty-prints data structures. You can set it to be the default formatter:

from pprint import pformat
show.set(fmtfunc=pformat)

# NB pformat, not pprint!

Or to configure pformat more precisely:

show.set(fmtfunc=lambda x: pformat(x, indent=4, width=120, depth=5))

Or you can set more complex pretty printing functions, using syntax highlighting and other transformations. As a convenience, show provides a method that uses pygments and pprint in concert to more attractively display text. Just:

show.prettyprint()

does the trick. It also takes indent, depth, and width options for pformat and the style (style name) option for pygments. Some style names to try:

# monokai manni rrt perldoc borland colorful default
# murphy vs trac tango fruity autumn bw emacs vim pastie
# friendly native

Showing What's Changed

show.changed()

will display the value of local variables. When invoked again, only those variables that have changed (since the last show.changed() in the same context) will be displayed.

You may omit some local variables if you like. By default, those starting with underscores (_) will be omitted, as will those containing functions, methods, builtins, and other parts Python program infrastructure. If you'd like to add those, or global variables into the mix, that's easily done:

show.changed(_private, MY_GLOBAL_VAR)

Will start watching those.

NB changed() used to be called watch(). The old watch() method will still work (it's just an alias to changed), but in the future it will be going away.

Interactive Limitations

show has draft support for both interactive Python and iPython. It works well at the interactive prompt, and within imported modules. It cannot, however, be used within functions and classes defined within the interactive session. This is due to how Python supprots--or fails to support--introspection in this instance. Whether this is a hard limit, or something that can be worked around over time, remains to be seen.

See e.g. this.

Python under Windows does not support readline the same way it is supported on Unix, Linux, and Mac OS X. As of version 0.60, experimental support is provided for the use of pyreadline under Windows to correct this variance. This feature is yet untested. Works/doesn't work reports welcome!

Notes

  • show is in its early days. Over time, it will provide additional context-specific output helpers. For example, the "diff" views of py.test seem a high-value enhancement.
  • Automated multi-version testing managed with the wonderful pytest and tox. show is successfully packaged for, and tested against, all late-model verions of Python: 2.6, 2.7, 3.2, and 3.3, as well as PyPy 1.9 (based on 2.7.2).
  • The author, Jonathan Eunice or @jeunice on Twitter welcomes your comments and suggestions.

Installation

To install the latest version:

pip install -U show

To easy_install under a specific Python version (3.3 in this example):

python3.3 -m easy_install --upgrade show

(You may need to prefix these with "sudo " to authorize installation.)

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.