Git Product home page Git Product logo

pudb's Introduction

PuDB: a console-based visual debugger for Python

Gitlab Build Status

Github Build Status

Python Package Index Release Page

Its goal is to provide all the niceties of modern GUI-based debuggers in a more lightweight and keyboard-friendly package. PuDB allows you to debug code right where you write and test it--in a terminal.

Here are some screenshots:

  • Light theme

    image

  • Dark theme

    image

You may watch screencasts too:

Features

  • Syntax-highlighted source, the stack, breakpoints and variables are all visible at once and continuously updated. This helps you be more aware of what's going on in your program. Variable displays can be expanded, collapsed and have various customization options.
  • Pre-bundled themes, including dark themes via "Ctrl-P". Could set a custom theme also.
  • Simple, keyboard-based navigation using single keystrokes makes debugging quick and easy. PuDB understands cursor-keys and Vi shortcuts for navigation. Other keys are inspired by the corresponding pdb commands.
  • Use search to find relevant source code, or use "m" to invoke the module browser that shows loaded modules, lets you load new ones and reload existing ones.
  • Breakpoints can be set just by pointing at a source line and hitting "b" and then edited visually in the breakpoints window. Or hit "t" to run to the line under the cursor.
  • Drop to a Python shell in the current environment by pressing "!". Or open a command prompt alongside the source-code via "Ctrl-X".
  • PuDB places special emphasis on exception handling. A post-mortem mode makes it easy to retrace a crashing program's last steps.
  • Ability to control the debugger from a separate terminal.
  • IPython integration (see wiki)
  • Should work with Python 3.6 and newer. (Versions 2019.2 and older continue to support Python 2.7.)

PuDB documentation

PuDB also has a mailing list that you may use to submit patches and requests for help. You can also send a pull request to the GitHub repository

Development Version

You may obtain the development version using the Git version control tool.:

git clone https://github.com/inducer/pudb.git

You may also browse the code online.

pudb's People

Contributors

alexfikl avatar alok avatar asmeurer avatar bulletmark avatar cfarrow avatar discort avatar eht16 avatar epmoyer avatar foxlisk avatar freed-wu avatar gaborvecseidocler avatar gregingelmo avatar hexagonrecursion avatar inducer avatar jen6 avatar jsoref avatar jstriebel avatar mlubimow avatar mm40 avatar mvanderkamp avatar nedbat avatar nmichaud avatar pvaret avatar qhuy4119 avatar ranelpadon avatar raphcode avatar swarmer avatar timgabets avatar wronglink avatar xywei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pudb's Issues

stop using distribute_setup

pudb probably doesn't really depend on distribute 0.6.35 but the way it is using distribute_setup makes it require distribute >= 0.6.35. This is inconvenient since the latest Ubuntu only includes 0.6.34.

Please just assume setuptools is available by removing "import distribute_setup". pip always runs every setup.py with setuptools enabled anyway.

version scheme

I'd encourage you to adopt a "classical" version scheme - see PEP 376

Should hooking the %pdb IPython magic be default?

Right now, when you import pudb.ipython, it hooks ip.debugger so that %pdb enables PuDB instead of ipdb. Should this be changed to not happen by default? If not, should we enable some way to disable it. I think right now if you have this in your IPython profile there is no way to get back to ipdb or pdb.

Examining a defaultdict adds a key of 0

Run pudb on this code:

import collections
d = collections.defaultdict(set)
print d
print len(d)

It will print:

defaultdict(<type 'set'>, {})
0

Now run the code in pudb again, but after d is created, open it in the Variables pane. It will have a key of 0 with an empty set as a value, and when the program is finished running, it will have printed:

defaultdict(<type 'set'>, {0: set([])})
1

Allow to set breakpoints on function definition

If you set a breakpoint on a def line, it only breaks there when the function is defined. But this is confusing, because the debugger goes to that line every time you step into that function. So it would be nice if a break point on a def line also caused the debugger to break whenever that function is called.

Different configuration for Python 3

I just found out that PuDB uses a different configuration file for Python 3? Why is this? It's kind of annoying, because I want the two to be identical, so I have to keep them in sync. It's impossible to use the same one for both via linking too because the Python 3 one uses [pudb3] and the Python 2 one uses [pudb].

Exceptions using search interface

I've come across two exceptions while using the / search functionality.

  1. Type / to search for something and hit Enter
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/urwid/decoration.py", line 225, in render
    canv = self._original_widget.render(size, focus=focus)
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/urwid/widget.py", line 1617, in render
    (maxcol,) = size
ValueError: too many values to unpack
  1. Type / to search for something and hit Esc
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/urwid/container.py", line 1103, in keypress
    return self.body.keypress( (maxcol, remaining), key )
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/urwid/container.py", line 2241, in keypress
    key = w.keypress((mc,) + size[1:], key)
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/urwid/container.py", line 1560, in keypress
    key = self.focus.keypress(tsize, key)
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/pudb/ui_tools.py", line 290, in keypress
    self.controller.cancel_search()
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/pudb/ui_tools.py", line 191, in cancel_search
    self.hide_search_ui()
  File "/home/lukelee/.virtualenvs/pyqt/local/lib/python2.7/site-packages/pudb/ui_tools.py", line 197, in hide_search_ui
    self.ui.lhs_col.set_focus(self.ui.lhs_col.widget_list[0])
IndexError: list index out of range

See where different debugging sessions diverge

This would be super hard to implement, but I'm putting it here in the hopes that someone will do it, or maybe point out an easy way to do it.

A common thing that I have to debug is two functions that give different things in different environments (say, two different git checkouts of some code, or whether or not a certain optional dependency is installed). The way I typically debug this with PuDB is to run the two side-by-side, and step through them both in parallel, and try to figure out exactly where they diverge.

This is super annoying, though, especially since it usually means stepping past the divergent point for each place in the stack, and then restarting and checking the next frame. Plus, it's easy to miss stuff, so that you have to restart again with no new information, and tricky to get the breakpointing right.

What I would like is some way to start PuDB from a given breakpoint (it has to be from a breakpoint, because e.g., if things differ from an optional dependency, I would want to skip things that diverge in unrelated code paths that do different setups when it is installed or not), and basically runs this schemata for me automatically, stopping when it notices the code going along a different path, or a variable set to a different value.

Local variables shadowed by global variables

Just started using pudb, and I ran into this issue and couldn't figure out what was going on:

If I have a test script like this:

i = None
def test(l):
    j = -1
    for i in range(len(l)):
        print l[i]
        print l[j]
test(range(10))

And then I:

  1. Run the script: python -m pudb.run test.py
  2. Set a break point on line 5 (print l[i])
  3. Continue until that break point is hit
  4. Create an interactive shell with '!'

I get this behavior:

>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print j
-1
>>> print i
None
>>> print l[i]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: list indices must be integers, not NoneType

Or in other words the value of i is None, which is the value in the global scope, not the local scope. I would expect this value to be be 0. All the other local variables (j and l) display the values I would expect.

Changing runtime state

Why is it that when I assign variables in the shell, these assignments are not reflected in the running programme? When I use pdb, I am able to freely change the values of variables and execute the programme with my changes.

Is this ability omitted intentionally?

Is it possible to add?

Add ability to break exactly when a variable changes

The whole point of watch expressions is that that is the expression you are interested in. So it would be useful to be able to press c and have the script stop exactly when it changes. This probably should be the default (though either way, there should be an option). At least, that's what the name "watch expression" suggests to me.

Double stack entries with post_mortem

I can't figure out what is going on here. If you try jedi, and use ./sith.py random code --pudb, where you replace code with some random Python code (like try PuDB's own code base), the stack items appear twice (note, jedi is highly recursive, so the stack traces will tend to be big and repetitive).

You'll need to use my pudb branch, which fixes pudb integration.

I've attached two screenshots showing what I mean. Notice how there are two >> in the stack trace.
screenshot 2013-07-25 19 23 26
screenshot 2013-07-25 19 23 31

crash when searching

Reproduction steps:

  1. python -m pudb.run foo.py
  2. /
  3. foo
  4. <enter>
  5. The below traceback is displayed.

If you can tell me how to induce this error automatically, I can write a unit test for it, at minimum, and likely produce a patch for the bug as well.

Traceback (most recent call last):
  File "/usr/lib/python2.6/bdb.py", line 46, in trace_dispatch                                                                                                                                               
    return self.dispatch_line(frame)                                                                                                                                                                         
  File "/usr/lib/python2.6/bdb.py", line 64, in dispatch_line                                                                                                                                                
    self.user_line(frame)                                                                                                                                                                                    
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/debugger.py", line 257, in user_line                                                                                                           
    self.interaction(frame)                                                                                                                                                                                  
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/debugger.py", line 226, in interaction                                                                                                         
    show_exc_dialog=show_exc_dialog)                                                                                                                                                                         
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/debugger.py", line 1256, in call_with_ui                                                                                                       
    return f(*args, **kwargs)                                                                                                                                                                                
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/debugger.py", line 1386, in interaction                                                                                                        
    self.event_loop()                                                                                                                                                                                        
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/debugger.py", line 1343, in event_loop                                                                                                         
    toplevel.keypress(self.size, k)                                                                                                                                                                          
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/ui_tools.py", line 82, in keypress                                                                                                             
    result = self._w.keypress(size, key)                                                                                                                                                                     
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/urwid/container.py", line 1103, in keypress                                                                                                         
    return self.body.keypress( (maxcol, remaining), key )                                                                                                                                                    
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/urwid/container.py", line 2241, in keypress                                                                                                         
    key = w.keypress((mc,) + size[1:], key)                                                                                                                                                                  
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/urwid/container.py", line 1560, in keypress                                                                                                         
    key = self.focus.keypress(tsize, key)                                                                                                                                                                    
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/ui_tools.py", line 294, in keypress                                                                                                            
    self.controller.hide_search_ui()                                                                                                                                                                         
  File "/home/buck/venv/mypy/lib/python2.6/site-packages/pudb/ui_tools.py", line 197, in hide_search_ui                                                                                                      
    self.ui.lhs_col.set_focus(self.ui.lhs_col.widget_list[0])                                                                                                                                                
IndexError: list index out of range                                                                                                                                                                          

Problems with pudb and IPython 0.12

I got this both in IPython 0.12 and the git master of IPython. If I type ! to go to IPython, I get the following. The first few frames up to _print_Pow are my debugging stack.

ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (101, 0))
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/Users/aaronmeurer/Documents/Python/sympy/sympy/<ipython-input-6-3a09c478a981> in <module>()
----> 1 pprint(g)

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/pretty/pretty.pyc in pretty_print(expr, **settings)
   1402 
   1403     """
-> 1404     print pretty(expr, **settings)
   1405 
   1406 pprint = pretty_print

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/pretty/pretty.pyc in pretty(expr, **settings)
   1373 
   1374     try:
-> 1375         return pp.doprint(expr)
   1376     finally:
   1377         pretty_use_unicode(uflag)

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/pretty/pretty.pyc in doprint(self, expr)
     40 
     41     def doprint(self, expr):
---> 42         return self._print(expr).render(**self._settings)
     43 
     44     # empty op so _print(stringPict) returns the same


/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/printer.pyc in _print(self, expr, *args)
    250                 printmethod = '_print_' + cls.__name__
    251                 if hasattr(self, printmethod):
--> 252                     return getattr(self, printmethod)(expr, *args)
    253 
    254             # Unknown object, fall back to the emptyPrinter.


/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/pretty/pretty.pyc in _print_Mul(self, product)
   1014                 b[i] = prettyForm(*self._print(b[i]).parens())
   1015             else:
-> 1016                 b[i] = self._print(b[i])
   1017 
   1018         # Construct a pretty form


/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/printer.pyc in _print(self, expr, *args)
    250                 printmethod = '_print_' + cls.__name__
    251                 if hasattr(self, printmethod):
--> 252                     return getattr(self, printmethod)(expr, *args)
    253 
    254             # Unknown object, fall back to the emptyPrinter.


/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/pretty/pretty.pyc in _print_Pow(self, power)
   1028         # square roots, other roots or n-th roots

   1029         #test for fraction 1/n or power x**-1

-> 1030         if power.is_commutative:
   1031             if (isinstance(power.exp, C.Rational) and power.exp.p==1 and power.exp.q !=1) or \
   1032                (   isinstance(power.exp, C.Pow) and

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/printing/pretty/pretty.pyc in _print_Pow(self, power)
   1028         # square roots, other roots or n-th roots

   1029         #test for fraction 1/n or power x**-1

-> 1030         if power.is_commutative:
   1031             if (isinstance(power.exp, C.Rational) and power.exp.p==1 and power.exp.q !=1) or \
   1032                (   isinstance(power.exp, C.Pow) and

/sw/lib/python2.7/bdb.pyc in trace_dispatch(self, frame, event, arg)
     46             return # None
     47         if event == 'line':
---> 48             return self.dispatch_line(frame)
     49         if event == 'call':
     50             return self.dispatch_call(frame, arg)

/sw/lib/python2.7/bdb.pyc in dispatch_line(self, frame)
     64     def dispatch_line(self, frame):
     65         if self.stop_here(frame) or self.break_here(frame):
---> 66             self.user_line(frame)
     67             if self.quitting: raise BdbQuit
     68         return self.trace_dispatch

/Users/aaronmeurer/Documents/pudb/pudb/debugger.pyc in user_line(self, frame)
    237         self.ui.update_breakpoints()
    238 
--> 239         self.interaction(frame)
    240 
    241     def user_return(self, frame, return_value):

/Users/aaronmeurer/Documents/pudb/pudb/debugger.pyc in interaction(self, frame, exc_tuple)
    206         self.set_frame_index(index)
    207 
--> 208         self.ui.call_with_ui(self.ui.interaction, exc_tuple)
    209 
    210     def get_stack_situation_id(self):

/Users/aaronmeurer/Documents/pudb/pudb/debugger.pyc in call_with_ui(self, f, *args, **kwargs)
   1240         self.show()
   1241         try:
-> 1242             return f(*args, **kwargs)
   1243         finally:
   1244             self.hide()

/Users/aaronmeurer/Documents/pudb/pudb/debugger.pyc in interaction(self, exc_tuple)
   1357 
   1358         self.caption.set_text(caption)
-> 1359         self.event_loop()
   1360 
   1361     def set_current_file(self, fname):

/Users/aaronmeurer/Documents/pudb/pudb/debugger.pyc in event_loop(self, toplevel)
   1316                         self.size = self.screen.get_cols_rows()
   1317                     else:
-> 1318                         toplevel.keypress(self.size, k)
   1319 
   1320             return self.quit_event_loop

/Users/aaronmeurer/Documents/pudb/pudb/ui_tools.pyc in keypress(self, size, key)
     85             for mask, handler in self.event_listeners:
     86                 if mask is None or mask == key:
---> 87                     return handler(self, size, key)
     88 
     89         return result

/Users/aaronmeurer/Documents/pudb/pudb/debugger.pyc in run_shell(w, size, key)
   1025 
   1026             runner(curframe.f_locals, curframe.f_globals,
-> 1027                     first_shell_run)
   1028 
   1029             self.screen.start()

/Users/aaronmeurer/Documents/pudb/pudb/shell.pyc in run_ipython_shell_v11(locals, globals, first_time)
    106     old_globals = shell.user_global_ns
    107     # Update shell with current namespace

--> 108     _update_ns(shell, locals, globals)
    109     shell.mainloop(banner)
    110     # Restore originating namespace


/Users/aaronmeurer/Documents/pudb/pudb/shell.pyc in _update_ns(shell, locals, globals)
    114     '''Update the IPython 0.11 namespace at every visit'''
    115     shell.user_ns = locals.copy()
--> 116     shell.user_global_ns = globals
    117     shell.init_user_ns()
    118     shell.init_completer()

AttributeError: can't set attribute

Then, when I execute any command that produces an Out result, I get:

In [8]: 1
Out[8]: 1
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/Users/aaronmeurer/Documents/Python/sympy/sympy/<ipython-input-8-b026324c6904> in <module>()
----> 1 1

/Users/aaronmeurer/Documents/ipython/IPython/core/displayhook.py in __call__(self, result)
    238             format_dict = self.compute_format_data(result)
    239             self.write_format_data(format_dict)
--> 240             self.update_user_ns(result)
    241             self.log_output(format_dict)
    242             self.finish_displayhook()

/Users/aaronmeurer/Documents/ipython/IPython/core/displayhook.py in update_user_ns(self, result)
    186 
    187         # Avoid recursive reference when displaying _oh/Out

--> 188         if result is not self.shell.user_ns['_oh']:
    189             if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
    190                 warn('Output cache limit (currently '+

KeyError: '_oh'

And finally, when I CTRL-D, I get

Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/sw/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/Users/aaronmeurer/Documents/ipython/IPython/core/interactiveshell.py", line 2743, in atexit_operations
    self.reset(new_session=False)
  File "/Users/aaronmeurer/Documents/ipython/IPython/core/interactiveshell.py", line 1131, in reset
    self.displayhook.flush()
  File "/Users/aaronmeurer/Documents/ipython/IPython/core/displayhook.py", line 255, in flush
    self.shell.user_ns['_oh'].clear()
KeyError: '_oh'
Error in sys.exitfunc:
Traceback (most recent call last):
  File "/sw/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/Users/aaronmeurer/Documents/ipython/IPython/core/interactiveshell.py", line 2743, in atexit_operations
    self.reset(new_session=False)
  File "/Users/aaronmeurer/Documents/ipython/IPython/core/interactiveshell.py", line 1131, in reset
    self.displayhook.flush()
  File "/Users/aaronmeurer/Documents/ipython/IPython/core/displayhook.py", line 255, in flush
    self.shell.user_ns['_oh'].clear()
KeyError: '_oh'

which kills everything and brings me back to bash (I think there are two tracebacks because I started pudb from within IPython).

python3 broken backtrace + typo

Try the code snippet below, do one single step which raises an exception.
Enter 'e' to show the exception. This kills pudb .
The reason is that the second component of

exc_tuple
is a string object while traceback/format_exception excepts it to be of type
Exception
.

Furthermore there is a typo in shell.py (line 27)

-    except Exception, e:
+    except Exception as e:

Thanks for looking into it,
Helmut.

# !/usr/bin/python3

from pudb import set_trace
L=['a','b','c']
set_trace()
i= L.index('e')

"""
Traceback (most recent call last):
  File "PUDB_T.py", line 7, in 
    i= L.index('e')
  File "/usr/lib64/python3.3/bdb.py", line 53, in trace_dispatch
    return self.dispatch_exception(frame, arg)
  File "/usr/lib64/python3.3/bdb.py", line 94, in dispatch_exception
    self.user_exception(frame, arg)
  File "/usr/lib64/python3.3/site-packages/pudb/debugger.py", line 279, in user_exception
    self.interaction(frame, exc_tuple)
  File "/usr/lib64/python3.3/site-packages/pudb/debugger.py", line 226, in interaction
    show_exc_dialog=show_exc_dialog)
  File "/usr/lib64/python3.3/site-packages/pudb/debugger.py", line 1256, in call_with_ui
    return f(_args, *_kwargs)
  File "/usr/lib64/python3.3/site-packages/pudb/debugger.py", line 1386, in interaction
    self.event_loop()
  File "/usr/lib64/python3.3/site-packages/pudb/debugger.py", line 1343, in event_loop
    toplevel.keypress(self.size, k)
  File "/usr/lib64/python3.3/site-packages/pudb/ui_tools.py", line 87, in keypress
    return handler(self, size, key)
  File "/usr/lib64/python3.3/site-packages/pudb/debugger.py", line 996, in show_traceback
    "".join(format_exception(*self.current_exc_tuple)))]),
  File "/usr/lib64/python3.3/traceback.py", line 181, in format_exception
    for value, tb in values:
  File "/usr/lib64/python3.3/traceback.py", line 122, in _iter_chain
    context = exc.__context__
AttributeError: 'str' object has no attribute '**context**'
"""

can't find ipython...

I set in preference to use ipython and it's available in my python path with version ipython-0.12-py2.7.egg. Pudb version is pudb-2012.1-py2.7.egg. However, everytime I hit !, I got the classic python shell. Any advice/steps to find out what went wrong? Thanks!

Pressing `.` or `,` without a search leads to an error

If you press . or , before entering a search term with /, it gives

Traceback (most recent call last):
  File "pudb/__init__.py", line 51, in runscript
    dbg._runscript(mainpyfile)
  File "pudb/debugger.py", line 315, in _runscript
    self.run(statement, globals=globals_, locals=locals_)
  File "/sw/lib/python2.7/bdb.py", line 387, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "debug_me.py", line 2, in <module>
    def simple_func(x):
  File "debug_me.py", line 2, in <module>
    def simple_func(x):
  File "/sw/lib/python2.7/bdb.py", line 48, in trace_dispatch
    return self.dispatch_line(frame)
  File "/sw/lib/python2.7/bdb.py", line 66, in dispatch_line
    self.user_line(frame)
  File "pudb/debugger.py", line 273, in user_line
    self.interaction(frame)
  File "pudb/debugger.py", line 242, in interaction
    show_exc_dialog=show_exc_dialog)
  File "pudb/debugger.py", line 1281, in call_with_ui
    return f(*args, **kwargs)
  File "pudb/debugger.py", line 1411, in interaction
    self.event_loop()
  File "pudb/debugger.py", line 1368, in event_loop
    toplevel.keypress(self.size, k)
  File "pudb/ui_tools.py", line 82, in keypress
    result = self._w.keypress(size, key)
  File "/sw/lib/python2.7/site-packages/urwid-1.1.1-py2.7-macosx-10.7-x86_64.egg/urwid/container.py",
line 1103, in keypress
    return self.body.keypress( (maxcol, remaining), key )
  File "/sw/lib/python2.7/site-packages/urwid-1.1.1-py2.7-macosx-10.7-x86_64.egg/urwid/container.py",
line 2241, in keypress
    key = w.keypress((mc,) + size[1:], key)
  File "/sw/lib/python2.7/site-packages/urwid-1.1.1-py2.7-macosx-10.7-x86_64.egg/urwid/container.py",
line 1560, in keypress
    key = self.focus.keypress(tsize, key)
  File "pudb/ui_tools.py", line 87, in keypress
    return handler(self, size, key)
  File "pudb/debugger.py", line 807, in search_previous
    self.search_controller.perform_search(dir=-1, update_search_start=True)
  File "pudb/ui_tools.py", line 234, in perform_search
    start = self.search_start
AttributeError: 'SearchController' object has no attribute 'search_start'

(by the way, selecting the traceback from the dialog is not as simple as it could be, even if you have rectangular selection)

curses.setupterm(), TypeError: argument must be an int, or have a fileno() method

I'm using pudb==2013.3.3.

When I add to my code:

import pudb; pudb.set_trace()

I get the following traceback:

Traceback (most recent call last):
  File "/home/aconrad/foo/tests/server/test_jsonschema_metadata.py", line 19, in test_question_display_rule
    import pudb; pudb.set_trace()
  File "/home/aconrad/.virtualenvs/foo/local/lib/python2.7/site-packages/pudb/__init__.py", line 138, in set_trace
    dbg = _get_debugger()
  File "/home/aconrad/.virtualenvs/foo/local/lib/python2.7/site-packages/pudb/__init__.py", line 26, in _get_debugger
    dbg = Debugger(**kwargs)
  File "/home/aconrad/.virtualenvs/foo/local/lib/python2.7/site-packages/pudb/debugger.py", line 136, in __init__
    self.ui = DebuggerUI(self)
  File "/home/aconrad/.virtualenvs/foo/local/lib/python2.7/site-packages/pudb/debugger.py", line 1187, in __init__
    curses.setupterm()
TypeError: argument must be an int, or have a fileno() method.

I'm using the Python that is shipped with Ubuntu 13.04:

$ python
Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] on linux2

Allow pausing while running

Sometimes I'll be running a program, and then it stalls so bad and I have no idea why.

In my main debugger, I'm able to pause execution by pressing Shift-F5. Then I can see which line the program is stuck on. A similar feature in pudb would help.

pudb has no test suite

I really love pudb. I use it multiple times a day. It has a few bugs which prevent me from recommending it wholeheartedly to my colleagues. I'd prefer to fix these myself, and send you a pull request, but the first step of my process is to add a failing test.

I see no way to do this with the current code base. Will you please add a test suite with demonstrates at least a couple basic features of pudb? I highly recommend py.test as a test runner. See my own RefactorLib for an example of how to set up with py.test and integrate with setuptools.

If there does exist a test system, please show me and you may close this ticket.

Allow to run to empty lines or lines with comments

So, for once, I am going to request a feature without implementing it. This touches on the actual debugging code, which I feel much less comfortable hacking. Also, the way it's currently implemented, some things would have to be redisigned non-trivially. And I really do need to get back to hacking SymPy :)

Basically, it would be nice if you could run to empty lines, or lines with comments. I wouldn't mind if this was really just a shortcut for running to the next actual runnable line, or if it's at the end of a file, to just run everything without giving the "Finished" dialog).

There are probably some nuances I am not considering here (e.g., could there be problems involved with return statements?). So I am going to just leave this here and hope that Andreas or someone else implements it.

Improve breakpoints view

@asmeurer said in #90: (since moved from there to here)

I actually realized that the breakpoints view could use some work anyway. I've never been a big user of breakpoints, though so I haven't noticed these before. There should be a visual indication on the breakpoint if it is active or not (I'm thinking some character in the already empty space to the left of each breakpoint). A keyboard shortcut to disable a breakpoint without deleting it would be useful, and a keyboard shortcut to jump to the location might be nice too. Any thoughts on this?

I'm thinking:

  • * (to the left of a breakpoint) means it is active
  • s (to the left of the breakpoint, next to the *) means it is a set_trace breakpoint. We could put other letters there too to indicate state about the breakpoint if it's useful.
  • b (?) disables/enables the breakpoint. Maybe another key is better, but this matches the key used in the code view.
  • l jumps to the location of the breakpoint (also not sure about this, so feel free to suggest something better. Maybe L is better since that matches the "goto" function in the code).

toggle breakpoints in .txt file accidently

I'm using vim-pudb to toggle breakpoints directly while editing the python file. Accidently, I press my shortcut keybinds to toggle a breakpoint on a .txt file. then pudb crashed. it throws out an syntax error.

[oliveagle@myhost python ]$ pudb test.py
Traceback (most recent call last):
File "/usr/local/share/python/pudb", line 9, in
load_entry_point('pudb==2013.2', 'console_scripts', 'pudb')()
File "/Library/Python/2.7/site-packages/pudb/run.py", line 30, in main
steal_output=options.steal_output)
File "/Library/Python/2.7/site-packages/pudb/init.py", line 24, in runscript
dbg = _get_debugger(steal_output=steal_output)
File "/Library/Python/2.7/site-packages/pudb/init.py", line 12, in _get_debugger
dbg = Debugger(**kwargs)
File "/Library/Python/2.7/site-packages/pudb/debugger.py", line 151, in init
for bpoint_descr in load_breakpoints():
File "/Library/Python/2.7/site-packages/pudb/settings.py", line 409, in load_breakpoints
return parse_breakpoints(lines)
File "/Library/Python/2.7/site-packages/pudb/settings.py", line 375, in parse_breakpoints
if get_breakpoint_invalid_reason(filename, lineno) is None:
File "/Library/Python/2.7/site-packages/pudb/lowlevel.py", line 48, in get_breakpoint_invalid_reason
if lineno not in get_executable_lines_for_file(filename):
File "/Library/Python/2.7/site-packages/pudb/lowlevel.py", line 23, in get_executable_lines_for_file
codes = [compile("".join(getlines(filename)), filename, "exec")]
File "/usr/local/share/vim/vim73/doc/help.txt", line 1
help.txt For Vim version 7.3. Last change: 2010 Jul 20
^

pudb come back after delete that breakpoint in saved-breakpoints directly.

So. I think pudb should check whether a breakpoint is added from a .py file or not before save that breakpoint in 'saved-breakpoints' file. and handle exceptions gracefully while parsing breakpoints.

p.s.
It would be better to make it clear where to find those 'saved-breakpoints' file without dig into the source code.

pudb freezes, sometimes, when pressing cursor keys

pudb occasionally freezes when debugging parts of a project of mine. It runs ok, as long as I use only standard debug keys( n, s, u, etc). The moment I call up a dialog ( pressing ?, for example) or press a cursor key, it freezes.
I suspect it's some module I'm importing, since it started recently and only in some of my sub-projects, but can't figure out what. Any pointers?

error while searching code (via '/' key) during debug session

Traceback (most recent call last):
File "/home/jtriley/py-workspace/starcluster/starcluster/cluster.py", line 1316, in run_plugin
func(_args)
File "/home/jtriley/py-workspace/starcluster/starcluster/plugins/tmux.py", line 152, in run
self.setup_tmuxcc(user='root')
File "/home/jtriley/py-workspace/starcluster/starcluster/plugins/tmux.py", line 119, in setup_tmuxcc
if node.alias != client.alias:
File "/home/jtriley/py-workspace/starcluster/starcluster/plugins/tmux.py", line 119, in setup_tmuxcc
if node.alias != client.alias:
File "/usr/lib/python2.6/bdb.py", line 46, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib/python2.6/bdb.py", line 64, in dispatch_line
self.user_line(frame)
File "/home/jtriley/py-workspace/pudb/pudb/debugger.py", line 233, in user_line
self.interaction(frame)
File "/home/jtriley/py-workspace/pudb/pudb/debugger.py", line 202, in interaction
self.ui.call_with_ui(self.ui.interaction, exc_tuple)
File "/home/jtriley/py-workspace/pudb/pudb/debugger.py", line 1177, in call_with_ui
return f(_args, **kwargs)
File "/home/jtriley/py-workspace/pudb/pudb/debugger.py", line 1286, in interaction
self.event_loop()
File "/home/jtriley/py-workspace/pudb/pudb/debugger.py", line 1248, in event_loop
toplevel.keypress(self.size, k)
File "/home/jtriley/py-workspace/pudb/pudb/ui_tools.py", line 82, in keypress
result = self._w.keypress(size, key)
File "/home/jtriley/.virtualenvs/starcluster/lib/python2.6/site-packages/urwid/container.py", line 616, in keypress
return self.body.keypress( (maxcol, remaining), key )
File "/home/jtriley/.virtualenvs/starcluster/lib/python2.6/site-packages/urwid/container.py", line 1340, in keypress
key = w.keypress( (mc,)+size[1:], key )
File "/home/jtriley/.virtualenvs/starcluster/lib/python2.6/site-packages/urwid/container.py", line 902, in keypress
key = self.focus_item.keypress( tsize, key )
File "/home/jtriley/py-workspace/pudb/pudb/ui_tools.py", line 208, in keypress
self.ui.search_AttrMap.set_attr("search box")
AttributeError: 'AttrMap' object has no attribute 'set_attr'

Blacklist modules when stepping through source code

Hi! (Love pudb, been using it for a long time now).

This is a feature request that just came up for a way to blacklist modules when nexting. The reason being that t is great when you're not switching stack frames, or switching but then switching back immediately, but for other times, say, when debugging an application running in an event loop or using big chunks of a large library where you want to skip the module running the event loop or the third-party code, it'd be nice to have a way to blacklist.

If you don't have time for this, consider it a reminder for myself, I'll try to get to it at some point if I beat you to it.

Thanks.

2013.6 release?

Can we get a fresh release of pudb up onto pypi?

There are several recent bugfixes that I'd like my coworkers to have, and our infra team dislikes tracking github, with good reason.

python3 broken backtrace - a tentative patch

Try the code snippet below, do one single step which raises an exception.
Enter 'e' to show the exception. This kills pudb .
#!/usr/bin/python3
from pudb import set_trace
L=['a','b','c']
set_trace()
i= L.index('e')

The reason for the failure seems to be the keyword parameter chain to
format_exception which is true by default.

Unfortunately I don't know how to attach a patch to this issue.
Here is plain text, I hope this might be a first step to fix this issue,
Helmut

--- pudb/debugger.py.ORIG   2013-03-07 12:06:38.749694164 +0100
+++ pudb/debugger.py    2013-03-07 12:08:17.819697885 +0100
@@ -935,8 +935,9 @@
                             from traceback import format_exception
                             import sys

+                            exc_info= sys.exc_info()
                             self.message("Could not import module '%s':\n\n%s" % (
-                                new_mod_name, "".join(format_exception(*sys.exc_info()))),
+                                new_mod_name, "".join(format_exception(*exc_info,chain=not isinstance(exc_info[1],str)))),
                                 title="Import Error")
                         else:
                             show_mod(sys.modules[str(new_mod_name)])
@@ -1017,7 +1018,7 @@

                 result = self.dialog(
                         urwid.ListBox([urwid.Text(
-                            "".join(format_exception(*self.current_exc_tuple)))]),
+                            "".join(format_exception(*self.current_exc_tuple,chain=not isinstance(self.current_exc_tuple[1],str))))]),
                         [
                             ("Close", "close"),
                             ("Location", "location")
@@ -1394,7 +1395,7 @@
                         "time using the 'e' key. "
                         "The debugger has entered post-mortem mode and will prevent further "
                         "state changes.\n\n"
-                        + "".join(format_exception(*exc_tuple)),
+                        + "".join(format_exception(*exc_tuple,chain=not isinstance(exc_tuple[1],str))),
                         title="Program Terminated for Uncaught Exception")

             caption.extend([
@@ -1437,9 +1438,9 @@
                             decoded_lines, set(breakpoints))
                 except:
                     from traceback import format_exception
-
+                    exc_info= sys.exc_info()
                     self.message("Could not load source file '%s':\n\n%s" % (
-                        fname, "".join(format_exception(*sys.exc_info()))),
+                        fname, "".join(format_exception(*exc_info,chain=not isinstance(exc_info[1],str)))),
                         title="Source Code Load Error")
                     self.source[:] = [SourceLine(self,
                         "Error while loading '%s'." % fname)]
@@ -1534,7 +1535,7 @@

         self.message(
                 "".join(format_exception(
-                    exc_type, exc_value, traceback)),
+                    exc_type, exc_value, traceback,chain=not isinstance(exc_value,str))),
                 title="Exception Occurred")

     # }}}

Ability to examine a non-executing namespace

Using m, it's possible to jump to a given module, but there's no way to look at its namespace, either in the variables view, or in the ! terminal. Is this possible? It would be also nice to be able to get at functions namespaces in those module, though that's not as important. This way, I could examine some global variables easier.

And by the way, unless this is trivial to implement, it's not really high priority.

Crash when running with urwid 1.0.0

A recent update to urwid (version 1.0.0) causes a crash in pudb (version 0.9.9.2 works correctly):

Traceback (most recent call last):
File "pudb/init.py", line 62, in runscript
dbg.runscript(mainpyfile)
File "pudb/debugger.py", line 276, in runscript
self.run(statement, globals=globals
, locals=locals
)
File "/usr/local/lib/python2.7/bdb.py", line 383, in run
exec cmd in globals, locals
File "", line 1, in
File "/home/elig/source/investigate/investigate.py", line 2, in
import os, sys
File "/home/elig/source/investigate/investigate.py", line 2, in
import os, sys
File "/usr/local/lib/python2.7/bdb.py", line 48, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/local/lib/python2.7/bdb.py", line 66, in dispatch_line
self.user_line(frame)
File "pudb/debugger.py", line 237, in user_line
self.interaction(frame)
File "pudb/debugger.py", line 206, in interaction
self.ui.call_with_ui(self.ui.interaction, exc_tuple)
File "pudb/debugger.py", line 1224, in call_with_ui
return f(_args, *_kwargs)
File "pudb/debugger.py", line 1339, in interaction
self.event_loop()
File "pudb/debugger.py", line 1298, in event_loop
toplevel.keypress(self.size, k)
File "pudb/ui_tools.py", line 87, in keypress
return handler(self, size, key)
File "pudb/debugger.py", line 1070, in do_edit_config
self.run_edit_config()
File "pudb/debugger.py", line 1133, in run_edit_config
edit_config(self, CONFIG)
File "pudb/settings.py", line 293, in edit_config
title="Edit Preferences"):
File "pudb/debugger.py", line 1195, in dialog
return self.event_loop(w)[0]
File "pudb/debugger.py", line 1290, in event_loop
canvas = toplevel.render(self.size, focus=True)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/decoration.py", line 219, in render
canv = self._original_widget.render(size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/container.py", line 443, in render
self.top_w_size(size, left, right, top, bottom), focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 1318, in render
canv = get_delegate(self).render(size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/container.py", line 875, in render
focus=focus and item_focus )
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/container.py", line 1228, in render
focus = focus and self.focus_col == i)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 1318, in render
canv = get_delegate(self).render(size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/container.py", line 875, in render
focus=focus and item_focus )
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/container.py", line 1228, in render
focus = focus and self.focus_col == i)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 132, in cached_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 1318, in render
canv = get_delegate(self).render(size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/widget.py", line 170, in finalize_render
canv = fn(self, size, focus=focus)
File "/usr/local/lib/python2.7/site-packages/urwid/listbox.py", line 351, in render
raise ListBoxError, "Focus Widget %r at position %r within listbox calculated cursor coords %r but rendered cursor coords %r!" %(focus_widget,focus_pos,cursor,c_cursor)
ListBoxError: Focus Widget <Padding selectable flow widget <AttrMap selectable flow widget <Edit selectable flow widget '' edit_pos=0> attr_map={None: 'value'}> left=4> at position 13 within listbox calculated cursor coords (3, 0) but rendered cursor coords None!

running set_trace() multiple times displays stdlib bdb.py

Reproduction steps:

  1. Save below script as foobar.py
  2. python foobar.py foo bar
  3. You'll break at function foo
  4. Defined a breakpoint at foobar.py:11 (the first line of main(): for arg in argv:)
  5. c
  6. You'll be brought to line 11
  7. c
  8. You'll be brought to /usr/lib/python2.6/bdb.py at _ste_stopinfo(), and also see that you now have two breakpoints at foobar.py:11
  9. Pressing s fourteen times eventually brings you to the correct breakpoint in bar()

The expected behavior is to not display bdb.py, and not create duplicate breakpoints.

Obviously there are other ways to accomplish the desired debugging session, but in a large, complex code base, it is sometimes extremely convenient to have multiple set_trace lines, which may or may not cause set_trace to be called twice.

If you can tell me how to induce this error automatically, I can write a unit test for it, at minimum, and likely produce a patch for the bug as well.

# Script: foobar.py
def foo():
    import pudb; pudb.set_trace()
    print 'foo'

def bar():
    import pudb; pudb.set_trace()
    print 'bar'

def main(argv):
    for arg in argv:
        if arg == 'foo':
            foo()
        elif arg == 'bar':
            bar()

import sys
main(sys.argv)

Screen flashes at each step

This has always been an issue for me. Each time I step through a line of code, the screen flashes. If the line takes a long time to complete, all I can see is my original prompt (bash or IPython or whatever). This is annoying when stepping through code, because the flashing is disorienting, and it's also annoying when executing a long line of code, because I can no longer see what is executing until it is done. This also happens a lot if there are print statements, as the statement is printed at the "original prompt".

Is this easily fixable, or is it an Urwid issue? I haven't looked at the code yet, but maybe just the screen redrawing commands need to be reorganized a little bit. Can you also reproduce this?

Deleting 'dead' breakpoints causes crash

If you make a change to your source file (specifically deleting lines) that puts an existing breakpoint past the end of your file, and then you restart Pudb and try to delete that breakpoint, Pudb throws the following exception and enters post-mortem:

File "/usr/lib/python3.3/site-packages/pudb/debugger.py", line 651, in delete_breakpoint self.source[bp.line-1].set_breakpoint(False) IndexError: list index out of range

So, for example, if I have a 100 line file and I have a breakpoint on line 95, if I then delete 10 lines and restart Pudb, the breakpoint on line 95 will still exist, even though my file is only 90 lines. But if I try to delete that breakpoint, Pudb will throw an exception and enter post-mortem. If I quit and then re-open, the breakpoint is cleared. It is also possible to clear these dead breakpoints manually while in post-mortem.

Would it make sense for these 'dead' breakpoints to be cleared on restart?

Python3 setup.py install fails

I was able to build using python3 setup.py build. But doing a setup.py install failed with the following traceback.

zip_safe flag not set; analyzing archive contents...
pudb.pycache.debugger.cpython-33: module references file
Traceback (most recent call last):
File "setup.py", line 47, in
packages=["pudb"])
File "/home/vagrant/sandbox/python3/lib/python3.3/distutils/core.py", line 148, in setup
dist.run_commands()
File "/home/vagrant/sandbox/python3/lib/python3.3/distutils/dist.py", line 917, in run_commands
self.run_command(cmd)
File "/home/vagrant/sandbox/python3/lib/python3.3/distutils/dist.py", line 936, in run_command
cmd_obj.run()
File "/home/vagrant/sandbox/python3/lib/python3.3/site-packages/distribute-0.6.29dev-py3.3.egg/setuptools/command/install.py", line 73, in run
self.do_egg_install()
File "/home/vagrant/sandbox/python3/lib/python3.3/site-packages/distribute-0.6.29dev-py3.3.egg/setuptools/command/install.py", line 93, in do_egg_install
self.run_command('bdist_egg')
File "/home/vagrant/sandbox/python3/lib/python3.3/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "/home/vagrant/sandbox/python3/lib/python3.3/distutils/dist.py", line 936, in run_command
cmd_obj.run()
File "/home/vagrant/sandbox/python3/lib/python3.3/site-packages/distribute-0.6.29dev-py3.3.egg/setuptools/command/bdist_egg.py", line 227, in run
os.path.join(archive_root,'EGG-INFO'), self.zip_safe()
File "/home/vagrant/sandbox/python3/lib/python3.3/site-packages/distribute-0.6.29dev-py3.3.egg/setuptools/command/bdist_egg.py", line 266, in zip_safe
return analyze_egg(self.bdist_dir, self.stubs)
File "/home/vagrant/sandbox/python3/lib/python3.3/site-packages/distribute-0.6.29dev-py3.3.egg/setuptools/command/bdist_egg.py", line 402, in analyze_egg
safe = scan_module(egg_dir, base, name, stubs) and safe
File "/home/vagrant/sandbox/python3/lib/python3.3/site-packages/distribute-0.6.29dev-py3.3.egg/setuptools/command/bdist_egg.py", line 435, in scan_module
symbols = dict.fromkeys(iter_symbols(code))
File "/home/vagrant/sandbox/python3/lib/python3.3/site-packages/distribute-0.6.29dev-py3.3.egg/setuptools/command/bdist_egg.py", line 457, in iter_symbols
for name in code.co_names: yield name
AttributeError: 'int' object has no attribute 'co_names'

Mention minimal python version in readme

pudb will not work in Python versions less than 2.5 because it imports functools into debugger.py

I think the minimal version should be mentioned in readme text. It might also help to introduce the minimal level to configuration for setup.py

Personally - I found a definition of partial on http://docs.python.org/library/functools.html?highlight=functools#functools.partial So I changed line 401 of /.../pudb-2012.3-py2.4.egg/pudb/debugger.py to become

try:
    from functools import partial
except ImportError:
    def partial(func, *args, **keywords):
        def newfunc(*fargs, **fkeywords):
            newkeywords = keywords.copy()
            newkeywords.update(fkeywords)
            return func(*(args + fargs), **newkeywords)
        newfunc.func = func
        newfunc.args = args
        newfunc.keywords = keywords
        return newfunc

and all was fine

Catch exceptions in continue mode

Sorry if there is already a way to do this, I didn't see it. If you are stepping through the debugger and an exception is thrown, you the debugger catches it, and you can analyze it. But if the debugger is just running (i.e., you pressed c to continue), exceptions are not caught, but rather the whole thing exits with a traceback. It would be nice if these exceptions were also caught.

pudb takes a long time to display GUI, taking 100% CPU

I am working with a pretty big code base and when hitting a pudb.set_trace() the thread goes to 100% CPU and stays there for almost one and a half minute before the pudb GUI shows up. Once when I interrupted it because I was tired of waiting I got this traceback:

Traceback (most recent call last):
  File "/usr/lib64/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/andersh/env_resolve/lib/python2.7/site-packages/pudb-2012.2-py2.7.egg/pudb/__main__.py", line 3, in <module>
    main()
  File "/home/andersh/env_resolve/lib/python2.7/site-packages/pudb-2012.2-py2.7.egg/pudb/run.py", line 30, in main
    steal_output=options.steal_output)
  File "/home/andersh/env_resolve/lib/python2.7/site-packages/pudb-2012.2-py2.7.egg/pudb/__init__.py", line 48, in runscript
    for bpoint_descr in load_breakpoints(dbg):
  File "/home/andersh/env_resolve/lib/python2.7/site-packages/pudb-2012.2-py2.7.egg/pudb/settings.py", line 389, in load_breakpoints
    return parse_breakpoints(lines)
  File "/home/andersh/env_resolve/lib/python2.7/site-packages/pudb-2012.2-py2.7.egg/pudb/settings.py", line 362, in parse_breakpoints
    if get_breakpoint_invalid_reason(filename, lineno) is None:
  File "/home/andersh/env_resolve/lib/python2.7/site-packages/pudb-2012.2-py2.7.egg/pudb/lowlevel.py", line 41, in get_breakpoint_invalid_reason
    if lineno not in get_executable_lines_for_file(filename):
  File "/home/andersh/env_resolve/lib/python2.7/site-packages/pudb-2012.2-py2.7.egg/pudb/lowlevel.py", line 16, in get_executable_lines_for_file
    codes = [compile("".join(getlines(filename)), filename, "exec")]
KeyboardInterrupt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.