Skip to content

Instantly share code, notes, and snippets.

@cemeyer
Created January 13, 2019 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cemeyer/e7b2bafb0285e90222b00b0b3b71b5fa to your computer and use it in GitHub Desktop.
Save cemeyer/e7b2bafb0285e90222b00b0b3b71b5fa to your computer and use it in GitHub Desktop.
Python2.7 'set -x' alike
# Use like: python setx.py my_python_program [args...]
#
# my_python_program can be a literal path to a file (e.g., foo.py), or the unqualified
# name of a Python program in PATH. In the latter case, setx.py examines PATH for
# a program with that name.
#
# Prints every line executed, including the filename and line number.
#
# This is a hacky prototype for py27; it almost certainly breaks in significant ways on
# non-Unix, or Python3000; and has only been tested on a FreeBSD derivative. It still
# may be interesting or a useful starting point for more portable implementations.
import bdb
import linecache
import os
import os.path
import sys
import __main__
skip_module_imports = True
log_exceptions = False
log_calls = False
class Xdb(bdb.Bdb):
def runfile(self, prog):
self._myprog = prog
self.run('execfile("%s")' % prog)
def user_call(self, frame, args):
if not log_calls:
return
name = frame.f_code.co_name
if not name:
name = '???'
fn = self.canonic(frame.f_code.co_filename)
print '+++ call', fn, frame.f_lineno, name, args
def user_line(self, frame):
import linecache
name = frame.f_code.co_name
if not name:
name = '???'
fn = self.canonic(frame.f_code.co_filename)
if fn == "<string>":
return
if "python2.7/sre_parse.py" in fn or "python2.7/sre_compile.py" in fn:
return
line = linecache.getline(fn, frame.f_lineno, frame.f_globals)
line = line.strip()
if skip_module_imports and line.startswith("import "):
self.set_next(frame)
else:
self.set_step()
print '+++', fn, frame.f_lineno, name, ':', line
def user_return(self, frame, retval):
if not log_calls:
return
print '+++ return', retval
def user_exception(self, frame, exc_stuff):
if not log_exceptions:
return
print '+++ exception', exc_stuff
def lookup(prog):
for d in os.environ.get("PATH", "").split(":"):
if not os.path.isdir(d):
continue
t = d + "/" + prog
if os.path.exists(t):
return t
import errno
raise FileNotFoundError(errno.ENOENT, prog)
if __name__ == "__main__":
del sys.argv[0]
prog = sys.argv[0]
if not os.path.exists(prog) and prog[0] != '/':
prog = lookup(prog)
sys.path[0] = os.path.dirname(os.path.realpath(prog))
__main__.__file__ = prog
Xdb().runfile(prog)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment