Introduction

Do you use print() or log() to debug your code? If so, peek will make printing debug information really easy. And on top of that, you get some basic benchmarking functionality.

Table of contents

Installation

Installing peek with pip is easy.

or when you want to upgrade,

Note that peek requires the asttokens, colorama, executing. six, tomli and pyperclip modules, all of which will be automatically installed.

Note

The GitHub repository can be found on https://github.com/salabim/peek .

Importing peek

All you need is:

, or the more conventional, but more verbose

Note that after this, peek is automatically a builtin and can thus be used in any module without importing it there.

Inspect variables and expressions

Have you ever printed variables or expressions to debug your program? If you've ever typed something like

or the more thorough

or:

then peek() is here to help. With arguments, peek() inspects itself and prints both its own arguments and the values of those arguments.

prints

Similarly,

prints

Just give peek() a variable or expression and you're done.

And you can even add color to distinguish between peek's output lines:

This will result in:

Inspect execution

Have you ever used print() to determine which parts of your program are executed, and in which order they're executed? For example, if you've ever added print statements to debug code like

then peek() helps here, too. Without arguments, peek() inspects itself and prints the calling line number and -if applicable- the file name and parent function.

prints something like

Return Value

peek() returns its argument(s), so peek() can easily be inserted into pre-existing code.

prints

Debug entry and exit of function calls

When you apply peek() as a decorator to a function or method, both the entry and exit can be tracked. The (keyword) arguments passed will be shown and upon return, the return value.

prints

It is possible to suppress the print-out of either the enter or the exit information with the show_enter and show_exit parameters, like:

prints

Benchmarking with peek

If you decorate a function or method with peek(), you will be offered the duration between entry and exit (in seconds) as a bonus.

That opens the door to simple benchmarking, like:

the ouput will show the effects of the population size on the sort speed:

It is also possible to time any code by using peek() as a context manager, e.g.

wil print something like

You can include parameters here as well:

will print somethink like:

Finally, to help with timing code, you can request the current delta with

or (re)set it with

So, e.g. to time a section of code:

might print something like:

Configuration

For the configuration, it is important to realize that peek is an instance of a class, which has a number of configuration attributes:

It is perfectly ok to set/get any of these attributes directly, like

But, it is also possible to apply configuration directly, only here, in the call to peek: So, it is possible to say

, which will print

It is also possible to configure several attributes permanently with the configure method.

will print in blue

It is arguably easier to say:

or even

to print

Yet another way to configure peek is to get a new instance of peek with peek.new() and the required configuration:

will print

Or, yet another possibility is to clone peek (optionally with modified attributes):

After this peek1 and peek2 will behave similarly (but they are not the same!)

prefix / pr

prints

prefix can be a function, too.

prints something like

output

This will allow the output to be handled by something else than the default (output being written to stdout).

The output attribute can be

In the example below,

As output may be a callable, you can even use this to automatically log any peek output:

will print to stdout:

Finally, you can specify the following strings:

E.g.

to print to stderr.

serialize

This will allow to specify how argument values are to be serialized to displayable strings. The default is pformat (from pprint), but this can be changed. For example, to handle non-standard datatypes in a custom fashion. The serialize function should accept at least one parameter. The function may optionally accept the keyword arguments width and sort_dicts, compact, indent, underscore_numbers and depth.

prints

show_line_number / sln

If True, adds the peek() call's line number and possibly the filename and parent function to peek()'s output.

prints something like

If "no parent" or "n", the parent function will not be shown.

prints something like

Note that if you call peek without any arguments, the line number is always shown, regardless of the status show_line_number.

See below for an explanation of the information provided.

show_time / st

If True, adds the current time to peek()'s output.

prints something like

show_delta / sd

If True, adds the number of seconds since the start of the program to peek()'s output.

prints something like

show_enter / se

When used as a decorator or context manager, by default, peek ouputs a line when the decorated the function is called or the context manager is entered.

With show_enter=False this line can be suppressed.

show_exit / sx

When used as a decorator or context manager, by default, peek ouputs a line when the decorated the function returned or the context manager is exited.

With show_exit=False this line can be suppressed.

show_traceback

When show_traceback is True, the ordinary output of peek() will be followed by a printout of the traceback, similar to an error traceback.

prints something like

The show_traceback functionality is also available when peek is used as a decorator or context manager.

line_length / ll

This attribute is used to specify the line length (for wrapping). The default is 80. Peek tries to keep all output on one line, but if it can't it will wrap:

prints

color / col and color_value / colv

The color attribute is used to specify the color of the output.

There's a choice of "black", "white", "red", "green", "blue", "cyan", "magenta", "yellow", " dark_black", "dark_white", "dark_red", "dark_green", "dark_blue", "dark_cyan", "dark_magenta" and "dark_yellow":

To set the color to 'nothing'", "use "-".

On top of that, color_value may be used to specify the value part of an output item. By specifying color_value as "" (the default), the value part will be displayed with the same color as the rest of the output.

For instance:

will result in:

Of course, color and color_value may be specified in a peek.toml file, to make all peek output in a specified color.

Note

The color and color_value attributes are only applied when using stdout as output.

Colors can be ignored completely by using peek.output = "stdout_nocolor.

compact

This attribute is used to specify the compact parameter for pformat (see the pprint documentation for details). compact is False by default.

prints

indent

This attribute is used to specify the indent parameter for pformat (see the pprint documentation for details). indent is 1 by default.

prints

depth

This attribute is used to specify the depth parameter for pformat (see the pprint documentation for details). depth is 1000000 by default.

prints

wrap_indent

This specifies the indent string if the output does not fit in the line_length (has to be wrapped). Rather than a string, wrap_indent can be also be an integer, in which case the wrap_indent will be that amount of blanks. The default is 4 blanks.

E.g.

prints

enabled

Can be used to disable the output:

prints

and nothing about a perfect world.

sort_dicts

By default, peek does not sort dicts (printed by pprint). However, it is possible to get the default pprint behaviour (i.e. sorting dicts) with the sorted_dicts attribute:

prints

Note that under Python <=3.7, dicts are always printed sorted.

underscore_numbers / un

By default, peek does not add underscores in big numbers (printed by pprint). However, it is possible to get the default pprint behaviour with the underscore_numbers attribute:

prints

Note that under Python <=3.7, numbers are never underscored.

seperator / sep

By default, pairs (on one line) are separated by ", ". It is possible to change this with the attribute separator:

prints

context_separator

By default the line_number, time and/or delta are followed by ==>. It is possible to change this with the attribute context_separator:

prints:

equals_separator

By default name of a variable and its value are separated by =. It is possible to change this with the attribute equals_separator:

prints:

quote_string / qs

If True (the default setting) strings will be displayed with surrounding quotes (like repr). If False, string will be displayed without surrounding quotes (like str). E.g.

This will print:

Note

This setting does not influence how strings are displayed within other data structures, like dicts and lists.

format / fmt

With the format attribute, it is possible to apply a format specifier to each of the values to be printed, like

This will print

The format should be like the Python format specifiers, with or without the : prefix, like "6.3f", ">10", "06d", :6.3d. It is also possible to use the ! format specifier: "!r", "!r:>10".

If format is the null string ("") (the default), this functionality is skipped completely.

It is also possible to use a list (or tuple) of format specifiers, which are tried in succession. If they all fail, the 'normal' serializer will be used.

will result in

Of course, format may be put in a peek.toml file.

values_only / vo

If False (the default), both the left-hand side (if possible) and the value will be printed. If True, the left hand side will be suppressed:

prints

values_only_for_fstrings / voff

If False (the default), both the original f-string and the value will be printed for f-strings. If True, the left_hand side will be suppressed in case of an f-string:

prints

Note that if values_only is True, f-string will be suppressed, regardless of values_only_for_fstrings.

end

The end attribute works like the end parameter of print. By default, end is "\n". This can be useful to have several peek outputs on one line, like:

Maybe more useful is to show the output change on the same line, e.g. a status.

The end parameter will be only applied when output is stdout, stdout_nocolor or stderr.

Note

\r does not work under Pythonista.

return_none

Normally, peek()returns the values passed directly, which is usually fine. However, when used in a notebook or REPL, that value will be shown, and that can be annoying. Therefore, if return_noneis True, peek()will return None and thus not show anything.

prints

delta

The delta attribute can be used to (re)set the current delta, e.g.

prints a value that id slightly more than 0.

print_like / print

When print_like (or print) is False, peek will work by expanding the arguments to description/serialized value pairs. But, when print_like is True, peek becomes a kind of supercharged print:

will print

in yellow, but only if peek.enabled is False, nothing will be printed.

You can also use peek.print (see below).

Tip

Of course, print_only can be put in a peek.toml file.

Use peek.print to use peek like print with extras

The method peek.print allows peek to be used as alternative to print. Note that peek.print applies the color, context_separator, enabled, filter and output, show_delta and show_time. It is also possible to redirect the output to as string with as_str.

So,

will print

in red, but only if peek.enabled is True (which is the default).

The peek.print() method applies the prefix, show_delta, show_line_number, show_time, show_ end attributes to the output.

In order to behave similar to print, peek has an extra attribute, separator_print (alias: sepp). This attribute (default " ") will be used when peek.printing. When calling peek.print, sep may be used instead. So

Has the same effect as

and

but not the same as

Note

peek.print does not obey the line length and will always return None (unless as_str is True).

Peeking locals and globals

It is possible to get the name and values of all local or global variables.

To do that, just put locals or globals in the call to peek, e.g.:

will print all local variables, apart from those starting with __, so:

Likewise,

will print all global variables, apart from those starting with __

Important

You should not add parentheses after locals or globals for peek to work properly!

Return a string instead of sending to output

peek(*args, as_str=True) is like peek(*args) but the output is returned as a string instead of written to output.

prints

Note that if enabled=False, the call will return the null string ("").

It is also possible to return a string with the embedded ANSI color escape strings, which can be useful to process the output in another program that supports ANSI colors, like salabim. This is done by setting the as_colored_str argument to True:

prints

Note

Specifying both as_str and as_colored_str is not allowed.

 

Disabling peek's output

prints

Of course peek() continues to return its arguments when disabled.

It is also possible to suppress output with the provided attribute (see above).

Using filter to control peek output

It is possible to define a filter function that determines whether peek output should be suppressed By default, the filter is defined as "" denoting no filter.

Suppose we a (float) level to a peek statement. By default, this level is 0. E.g.:

With peek.filter ="level <= 1" the program makes sure that level=2 is not displayed at all.

It is possible to use more than one attribute, like

As an alternative to enabled we can also say

Copying to the clipboard

It is possible to copy a value to the clipboard. There are two ways:

With peek(to_clipboard=True)

With the optional keyword argument, to_clipboard:

Examples:

Note that to_clipboard is a peek attribute.

If as_str==True, to_clipboard is ignored.

With peek.to_clipboard

Just use peek.to_clipboard to copy any value to the clipboard. So,

will copy 1234 to the clipboard and write copied to clipboard: 1234 to the console. If the confirmation message is not wanted, just add confirm=False, like

General

Implementation detail: the clipboard functionality uses pyperclip, apart from under Pythonista, where the builtin clipboard module is used.

This functionality is particularly useful for entering an answer of an Advent of Code solution to the site.

Interpreting the line number information

When show_line_number is True or peek() is used without any parameters, the output will contain the line number like:

If the line resides in another file than the main file, the filename (without the path) will be shown as well:

And finally when used in a function or method, that function/method will be shown as well:

The parent function can be suppressed by setting show_line_number or sln to "n" or "no parent".

Configuring at import time

It can be useful to configure peek at import time. This can be done by providing a peek.toml file which can contain any attribute configuration overriding the standard settings. E.g. if there is a peek.toml file with the following contents

in the same folder as the application, this program:

will print something like this to stderr (rather than stdout):

At import time current directory will be searched for peek.toml and if not found, one level up, etc. until the root directory is reached.

Please observe that toml values are slightly different from their Python equivalents:

Note that not-specified attributes will remain the default settings.

Just for your information, the core developer of peek uses a peek.toml file with the contents:

 

Working with multiple instances of peek

Normally, only the peek object is used.

It can be useful to have multiple instances, e.g. when some of the debugging has to be done with context information and others requires an alternative prefix.

There are several ways to obtain a new instance of peek:

In either case, attributes can be added to override the default ones.

Example

prints something like

ignore_toml

With peek.new(ignore_toml=True) an instance of peek without having applied any toml configuration file will be returned. That can be useful when guaranteeing the same output in several setups.

Example

Suppose we have a peek.toml file in the current directory with the contents

Then

prints

Test script

On GitHub is a file test_peek.py that tests (and thus also demonstrates) most of the functionality of peek.

It is very useful to have a look at the tests to see the features (some may be not covered (yet) in this readme).

Using peek in a REPL

Peek may be used in a REPL, but with limited functionality:

Note

Under Python >=3.13 most of the normal peek functionality is available in the REPL. A reason to upgrade!

Limitations

It is not possible to use peek:

Changelog

The changelog can be found here:

Acknowledgement

The peek package is inspired by the IceCream package, but is a nearly complete rewrite. See https://github.com/gruns/icecream

Many thanks to the author Ansgar Grunseid / grunseid.com / grunseid@gmail.com .

The peek package is a rebrand of the ycecream package, with many enhancements.

Differences with IceCream

The peek module was originally a fork of IceCream, but has many differences:

PyPI PyPI - Python Version PyPI - Implementation PyPI - License ruff GitHub last commit