PySnooper README

The project's README from github.com/cool-RR/PySnooper. As one markdown file: README.md.

PySnooper - Never use print for debugging again

PySnooper is a poor man's debugger. If you've used Bash, it's like set -x for Python, except it's fancier.

Your story: You're trying to figure out why your Python code isn't doing what you think it should be doing. You'd love to use a full-fledged debugger with breakpoints and watches, but you can't be bothered to set one up right now.

You want to know which lines are running and which aren't, and what the values of the local variables are.

Most people would use print lines, in strategic locations, some of them showing the values of variables.

PySnooper lets you do the same, except instead of carefully crafting the right print lines, you just add one decorator line to the function you're interested in. You'll get a play-by-play log of your function, including which lines ran and when, and exactly when local variables were changed.

What makes PySnooper stand out from all other code intelligence tools? You can use it in your shitty, sprawling enterprise codebase without having to do any setup. Just slap the decorator on, as shown below, and redirect the output to a dedicated log file by specifying its path as the first argument.

Example

We're writing a function that converts a number to binary, by returning a list of bits. Let's snoop on it by adding the @pysnooper.snoop() decorator:

import pysnooper

@pysnooper.snoop()
def number_to_bits(number):
    if number:
        bits = []
        while number:
            number, remainder = divmod(number, 2)
            bits.insert(0, remainder)
        return bits
    else:
        return [0]

number_to_bits(6)

The output to stderr is:

Or if you don't want to trace an entire function, you can wrap the relevant part in a with block:

import pysnooper
import random

def foo():
    lst = []
    for i in range(10):
        lst.append(random.randrange(1, 1000))

    with pysnooper.snoop():
        lower = min(lst)
        upper = max(lst)
        mid = (lower + upper) / 2
        print(lower, mid, upper)

foo()

which outputs something like:

New var:....... i = 9
New var:....... lst = [681, 267, 74, 832, 284, 678, ...]
09:37:35.881721 line        10         lower = min(lst)
New var:....... lower = 74
09:37:35.882137 line        11         upper = max(lst)
New var:....... upper = 832
09:37:35.882304 line        12         mid = (lower + upper) / 2
74 453.0 832
New var:....... mid = 453.0
09:37:35.882486 line        13         print(lower, mid, upper)
Elapsed time: 00:00:00.000344

Features

If stderr is not easily accessible for you, you can redirect the output to a file:

@pysnooper.snoop('/my/log/file.log')

You can also pass a stream or a callable instead, and they'll be used.

See values of some expressions that aren't local variables:

@pysnooper.snoop(watch=('foo.bar', 'self.x["whatever"]'))

Show snoop lines for functions that your function calls:

@pysnooper.snoop(depth=2)

See Advanced Usage for more options. <------

Installation with Pip

The best way to install PySnooper is with Pip:

$ pip install pysnooper

Other installation options

Conda with conda-forge channel:

$ conda install -c conda-forge pysnooper

Arch Linux:

$ yay -S python-pysnooper

Fedora Linux:

$ dnf install python3-pysnooper

Citing PySnooper

If you use PySnooper in academic work, please use this citation format:

@software{rachum2019pysnooper,
    title={PySnooper: Never use print for debugging again},
    author={Rachum, Ram and Hall, Alex and Yanokura, Iori and others},
    year={2019},
    month={jun},
    publisher={PyCon Israel},
    doi={10.5281/zenodo.10462459},
    url={https://github.com/cool-RR/PySnooper}
}

License

Copyright (c) 2019 Ram Rachum and collaborators, released under the MIT license.

Media Coverage

Hacker News thread and /r/Python Reddit thread (22 April 2019)

PySnooper (cool-RR/PySnooper)

Searching Database…

16.6K ·GitHub
这是干什么的?PySnooper 是一个 Python 调试工具,能跟踪一个函数并记录它执行的每一行代码和局部变量的变化,就像 Bash 里的 set -x。一个装饰器就能替代一大堆手写的 print 语句。
它和我 IDE 里的完整调试器有什么区别?完整调试器需要设置断点和监视变量,遇到一个小 bug 时往往懒得去弄。PySnooper 就是走捷径:加一行装饰器,省去精心编写的 print 语句。
怎么在我自己的代码上使用?在想查看的函数上加上 @pysnooper.snoop() 装饰器。如果只关心函数中的一小段代码,可以把那段放进一个 with 块里,而不必跟踪整个函数。
它能应付庞大杂乱的生产代码库吗?能——零配置是它最大的卖点。只要把装饰器往出问题的函数上一贴就行,哪怕是在庞大的企业代码库里也没问题。
snoop 的输出到底长什么样?README 里演示了一个把数字转换为二进制位列表的函数。加上 snoop 装饰器后,stderr 会显示完整的执行过程:每一行代码何时运行、局部变量何时变化,一目了然。
我能在学术论文中引用 PySnooper 吗?可以,README 提供了在学术出版物中使用 PySnooper 的具体引用格式。
What are similar projects?icecream, memray, vConsole, rr, debug, loguru, delve, gdbgui
Creator
cool-RR
Size
0.4 MB
Stars
16.6K
Age
7y
Commits · 90 Days