Created
March 23, 2010 20:32
-
-
Save ltvolks/341619 to your computer and use it in GitHub Desktop.
Use TextMate Bookmarks as PDB breakpoints
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
mate_pdb.py | |
Execute a script file in the debugger using breakpoints set | |
via Bookmarked Lines in TextMate. | |
Intended usage is to call from within a TextMate Command in | |
your Python bundle | |
but can be called like so: | |
python mate_pdb.py scriptfile.py | |
This is functionally equivalent to: | |
python -m pdb scriptfile.py | |
If the xattributes exist for bookmarked lines, they will be added | |
as breakpoints to the pdb session. | |
Requires xattr module: http://pypi.python.org/pypi/xattr | |
Kickstarted by this listbot.org posting: http://listbot.org/blog/python/2010/03/22/pdb/ | |
TODO: | |
* Optionally use ipdb | |
* Execute until first set breakpoint instead of starting session on line 1 | |
""" | |
import os, sys, zlib | |
from pdb import Pdb | |
import xattr | |
def xattr_to_list(unzipped): | |
return (unzipped.replace('(','').replace(')','').replace('\n','').replace(' ','')).split(",") | |
def main(): | |
if not sys.argv[1:]: | |
print "usage: mate_pdb.py scriptfile [arg] ..." | |
sys.exit(2) | |
mainpyfile = sys.argv[1] # Get script filename | |
if not os.path.exists(mainpyfile): | |
print 'Error:', mainpyfile, 'does not exist' | |
sys.exit(1) | |
del sys.argv[0] # Hide "pdb.py" from argument list | |
# Replace pdb's dir with script's dir in front of module search path. | |
sys.path[0] = os.path.dirname(mainpyfile) | |
# Create breakpoint list from TM bookmark attributes | |
rcLines = [] | |
try: | |
breakpoint_list = xattr.getxattr('%s' % mainpyfile, 'com.macromates.bookmarked_lines') | |
except IOError, x: | |
# Attributes may not exist in the target script, ignore | |
pass | |
else: | |
try: | |
breakpoint_list = breakpoint_list.decode('zip') | |
except zlib.error: | |
pass | |
for breakpoint in xattr_to_list(breakpoint_list): | |
rcLines.append("b %s:%d\n" % (mainpyfile, (int(breakpoint) + 1))) | |
pdb = Pdb() | |
pdb.rcLines.extend(rcLines) | |
while 1: | |
try: | |
pdb._runscript(mainpyfile) | |
if pdb._user_requested_quit: | |
break | |
print "The program finished and will be restarted" | |
except SystemExit: | |
# In most cases SystemExit does not warrant a post-mortem session. | |
print "The program exited via sys.exit(). Exit status: ", | |
print sys.exc_info()[1] | |
except: | |
traceback.print_exc() | |
print "Uncaught exception. Entering post mortem debugging" | |
print "Running 'cont' or 'step' will restart the program" | |
t = sys.exc_info()[2] | |
while t.tb_next is not None: | |
t = t.tb_next | |
pdb.interaction(t.tb_frame,t) | |
print "Post mortem debugger finished. The "+mainpyfile+" will be restarted" | |
# When invoked as main program, invoke the debugger on a script | |
if __name__=='__main__': | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
########################################################################### | |
# Start Python in debug mode using either Terminal.app or iTerm.app | |
# Textmate bookmarks are set as breakpoints in the debug session | |
# Requires the existence of TM_PDB_SCRIPT (mate_pdb.py) to set | |
# breakpoints and run the target in the debugger | |
# | |
# Note also that if iTerm is used, it expects iPython to be available, so | |
# Terminal --> plain python | |
# iTerm --> iPython | |
# | |
# Installation: | |
# Add a new Command to the Python Bundle in TM: "Debug Script w/ Bookmarks" | |
# Set Activation: Key Equivalent = to your desired keystroke combo | |
# suggested : (SHIFT + APPLE + D) | |
# Scope Selector: source.python | |
# | |
# Add the mate_pdb.py script somewhere on your path and make sure to set | |
# TM_PDB_SCRIPT in TextMate. | |
# | |
# | |
# The following Shell Variables should be set in TextMate: | |
# | |
# TM_TERM_PROG = Terminal program (iTerm or Terminal) | |
# default = Terminal | |
# TM_PYTHON = python interpreter | |
# default = python | |
# TM_PDB_SCRIPT = path to mate_pdb.py script | |
# default = ~/bin/mate_pdb.py | |
# | |
########################################################################### | |
TP=${TM_TERM_PROG:=Terminal} | |
TPY=${TM_PYTHON:=python} | |
TMPDB=${TM_PDB_SCRIPT:=~/bin/mate_pdb.py} | |
USER_NAME=`whoami` | |
if [ "$TP" == iTerm ]; then | |
osascript <<END | |
tell application "iTerm" | |
activate | |
set myTerm to the first terminal | |
tell myTerm | |
-- Conditionally create ipython session | |
set sessionexists to ((count (get every session whose name is "iPython"))) | |
if sessionexists > 0 then | |
tell session "iPython" | |
--activate | |
write text "%run '$TMPDB' '$TM_FILEPATH'" | |
end tell | |
else | |
-- create new session | |
set ipysession to (make new session at the end of sessions) | |
tell ipysession | |
set name to "iPython" | |
exec command "login -fp $USER_NAME" | |
write text "cd '$TM_DIRECTORY'" | |
write text "clear" | |
write text "ipython" | |
write text "%run '$TMPDB' '$TM_FILEPATH'" | |
end tell | |
end if | |
end tell | |
end tell | |
END | |
else | |
osascript <<END2 | |
tell application "Terminal" | |
activate | |
do script with command "$TPY $TMPDB $TM_FILEPATH" | |
end tell | |
END2 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment