Skip to main content

python library for cool debugging of python progams.

Project description

ddebug

ddebug is a python library for simple debugging of python progams. It works only within a python file, not in the console.

ddebug is both icecream and snoop but simple and quick to use in the style of q.

ddebug works with python 3.6+.

Installation

Install using pip: (python -m) pip install ddebug

Simple Example

from ddebug import dd
@dd #do @snoop on a function
def foo(n):
    return n+333
@dd # do @snoop on all class functions (only possible in ddebug)
class A:
    def a(self):
        pass

dd(foo(123)) # use like icecream.

output:

12:30:49.47 >>> Call to foo in File "python-file.py", line 3
12:30:49.47 ...... n = 123
12:30:49.47    3 | def foo(n):
12:30:49.47    4 |     return n+333
12:30:49.47 <<< Return value from foo: 456
dd| foo(123): 456

More options

min cls:

Sometimes you don't want to view all the class functions internal processes, just see when it was called. Then you can use mincls(named also mc) option to just see the function call:

from ddebug import dd
@dd.mincls
class A:
    def a(self):
        pass

a = A()
a.a()

Output:

dd| python-file.py:8 in <module>: call method 'a' from class 'A' at 11:34:15.383

mincls does not yet support the __ <> __ functions(e.g. __ init __).

Concatenating

If you use ddebug as a function like icecream, e.g. dd(value) it will returns the arguments you passed in to it:

from ddebug import dd
a = "a"
b = "b"
c = dd(dd(a)+dd(b))
dd(c)

Output:

dd| a: 'a'
dd| b: 'b'
dd| dd(a)+dd(b): 'ab'
dd| c: 'ab'

Tracebacks

In ddebug there is an option for more detailed traceback than the regular traceback:

from ddebug import dd
#place at start of program
dd.set_excepthook()

Then when an error occurrs ddebug creates a file named <file>-errors.txt: the file starts with rich (render Python tracebacks with syntax highlighting and formatting) and then friendly explanation of the error.

In addition, you can press Enter within the first 5 seconds after exception and it will open the standard pdb.

If you don't want\can't use excepthook (because usually other modules use the excepthook), you can use atexit:

from ddebug import dd
dd.set_atexit()

if you want to choose file name: just pass file=<file> to the function.

watch

ddebug has a watch and unwatch (named also w and unw) uses watchpoints.

from ddebug import dd
a = []
dd.watch(a)
a = {}

Output

Watch trigger ::: File "python-file.py", line 4, in <module>
	a:was [] is now {}

By default all of this output is printed with the icecream printer. If you want to change this, do:

from ddebug import dd
import sys
dd.watch_stream = sys.stderr # or another file/stream as you want

install()

To make dd available in every file (without needing to import ddebug) just write in the first file:

from ddebug import dd
dd.install() # install only "dd" name
# you can chose an alias
dd.install(("dd","d"))

Disabling

dd has an attribute named enabled. Set to false to suppress output.

from ddebug import dd
dd(12) # will output ic(12)
dd.enabled = False
dd(12) # not output anything

This disabes @dd,dd(),dd.<un>watch and dd.mincls For disabling the excepthook do:

import sys
sys.excepthook = sys.__excepthook__

or comment out the call to `dd.set_excepthook()``.

Operations

dd has a lot of operations that are equal to dd(a):

from ddebug import dd
a = "a"
b = dd+a
b = dd*a
b = dd@a
b = dd>>a
b = dd<<a
b = a|dd
b = dd|a
b = dd&a

for example: instead of trying to add dd() to l = list(map(str,filter(bool,range(12)))) you can do l = dd @ list(map(str,filter(bool,range(12))))

Don't use <>=(e.g. +=) operations. icecream can't get source code and will throw a ScoreError.

print stack

if you want to see the current stack without raising an error do:

from ddebug import dd
#  print sorted (from last frame to call of dd.print_stack()) stack (takes some time)
dd.print_stack()
# print stack (quick) like traceback
dd.print_stack(sort=False)

Streams

If you want to write ddebug output to tmp file (like q) and also to stderr just do:

dd.add_tmp_stream()

If you want only a tmp file(without stderr):

dd.add_tmp_stream(with_print=False)

if you want to write only to custom file do:

dd.stream = open("output.txt","w")

Don't forget to close the file. If you do not close the file - the file will probably not write. My recommendation is to use built-inatexit module to close the file (you can use it even if you alredy use atexit (e.g. dd.set_atexit()):

import atexit
from ddebug import dd
output_stream = open("output.txt", "w")
atexit.register(output_stream.close) #will close the file at the end of the program
dd.stream = output_stream

All of them will remove color form stderr print.

All of them will affect:@dd,dd(), dd.mincls and dd.<un>watch.

Output folder

If you want to see all the output of ddebug in one folder you can do:

from ddebug import dd
dd.add_output_folder()  # then all output goes to folder and stderr - it will also remove color.

it will create a folder named <file>_log and create 3 .txt files:

  • watch-log - output from dd.<un>watch
  • snoop-log - output from @dd on class or function
  • icecream-log - output from dd(), @dd.mincls and dd.print_stack()

It will also set excepthook or atexit to create a file named error.txt in this folder. Pass with_errors=False to this function to prevent this.

If you dont want each run of the program to overwrite the files in the folder or you want to see the date your script was run - do:

dd.add_output_folder(with_date=True)

or:

dd.add_output_folder(True)

There is way to choose folder name using a file:

dd.add_output_folder(pyfile="python-file.py") # will create a folder python-file_log

or:

dd.add_output_folder(folder="my-cool-folder") # will create a folder my-cool-folder

config

You can config snoop common arguments with dd.snoop_short_config (named also ssc) with:

from ddebug import dd
dd.snoop_short_config(watch=('foo.bar', 'self.x["whatever"]'),watch_explode=['foo', 'self'])
@dd.ssc(watch=('foo.bar', 'self.x["whatever"]'))   # you even use that as the @dd
def foo(n):
    return n+333
foo(123)

You can config snoop with: dd.snoopconfig(snoop-config-options). All options but builtins and snoop names are valid.

You can config icecream.includeContext (dd() calls filename, line number, and parent function to dd output.) by:dd.icecream_includeContext = True.

you can config friendly.language by dd.friendly_lang = "<languages>"

with dd

with dd equal to with snoop.

more debbug tools:

inspect()

dd.inspect(obj) equal to rich.inspect

deep()

dd.deep equal to snoop.pp.deep

Dependencies

ddebug depends on the python librarys:

  • icecream - main dependency
  • snoop - main dependency
  • watchpoints - for dd.watch and dd.unwatch
  • inputimeout - to ask to start pdb debugger in error hooks
  • friendly - for explanation on the error in error-hooks
  • rich - to create the traceback before friendly-traceback in error hooks and for dd.inspect function

Contribute

On all errors, problems or suggestions please open a github issue

Buy Me A Coffee

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ddebug-0.3.0.tar.gz (12.0 kB view hashes)

Uploaded Source

Built Distribution

ddebug-0.3.0-py3-none-any.whl (11.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page