Created
January 13, 2019 00:38
-
-
Save cemeyer/e7b2bafb0285e90222b00b0b3b71b5fa to your computer and use it in GitHub Desktop.
Python2.7 'set -x' alike
This file contains hidden or 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
# 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