Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add script target
  • Loading branch information
gaogaotiantian committed Apr 25, 2023
commit fe694b9f334cf75d6c4ca1ab99daf70de475c043
68 changes: 68 additions & 0 deletions Lib/bdbx.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import argparse
import cmd
import dis
import io
import linecache
import os
import re
Expand Down Expand Up @@ -253,6 +255,28 @@ class StopEvent:
is_return: bool = False


class _ExecuteTarget:
pass


class _ScriptTarget(_ExecuteTarget):
def __init__(self, filename):
self.filename = filename
if not os.path.exists(filename):
raise FileNotFoundError(filename)
with io.open_code(filename) as f:
self.code = compile(f.read(), filename, "exec")

@property
def namespaces(self):
ns = {
'__name__': '__main__',
'__file__': self.filename,
'__builtins__': __builtins__,
}
return ns, ns


class Bdbx:
"""Bdbx is a singleton class that implements the debugger logic"""
_instance = None
Expand Down Expand Up @@ -383,6 +407,21 @@ def monitor_callback(self, frame, breakpoint, event, event_arg):
# ======================= Helper functions ===============================
# ========================================================================

def _run_target(self, target:_ExecuteTarget):
"""Debug the given code object in __main__"""
import __main__
main_dict = __main__.__dict__.copy()
globals, locals = target.namespaces
__main__.__dict__.clear()
__main__.__dict__.update(globals)
self.break_here()
try:
exec(target.code, globals, locals)
except BdbxQuit:
pass
__main__.__dict__.clear()
__main__.__dict__.update(main_dict)

def _get_stack_from_frame(self, frame):
"""Get call stack from the latest frame, oldest frame at [0]"""
stack = []
Expand All @@ -401,6 +440,11 @@ def __init__(self):
Bdbx.__init__(self)
cmd.Cmd.__init__(self, 'tab', None, None)

# ========================================================================
# ============================ User APIs =================================
# ========================================================================


# ========================================================================
# ======================= Interface to Bdbx ==============================
# ========================================================================
Expand Down Expand Up @@ -703,3 +747,27 @@ def do_where(self, arg):
def break_here():
pdb = Pdbx()
pdb.break_here(sys._getframe().f_back)


def main():
parser = argparse.ArgumentParser()
parser.add_argument('-m', nargs='?', default=None)
options, commands = parser.parse_known_args()

if options.m:
# Run module
pass
elif commands:
# Run scripts
target = _ScriptTarget(commands[0])
else:
# Show help message
parser.print_help()

pdbx = Pdbx()
pdbx._run_target(target)


if __name__ == '__main__':
import bdbx
bdbx.main()