Starting a python debugging session from a program, not from the console

I am writing a small python IDE and I want to add simple debugging. I do not need all winpdb functions. How to run a python program (by file name) with a breakpoint set on the line number so that it runs up to that line number and stops? Note that I do not want to do this from the command line, and I do not want to edit the source (for example, by inserting set_trace). And I do not want him to stop on the first line, so I have to debug from there. I tried all the obvious ways with pdb and bdb, but I have to skip something.

+5
source share
1 answer

Almost the only way to do this (as far as I know) is to run Python as a subprocess from your development environment. This avoids the “pollution” of the current Python interpreter, which makes it pretty likely that the program will work just as if you started it yourself. (If you have problems with this, check the subprocess environment.) That way, you can run the script in debug mode using

p = subprocess.Popen(args=[sys.executable, '-m', 'pdb', 'scriptname.py', 'arg1'],
                     stdin=subprocess.PIPE,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)

This will launch Python on the debugger command line. You will need to run some debugger commands to set breakpoints that you can do this:

o,e = p.communicate('break scriptname.py:lineno')

, o Python , , e . , , .

p.communicate('continue')

, , , , IDE. , , :

while p.returncode is None:
    o,e = p.communicate(console.read())
    console.write(o)
    console.write(e)

, , , , , .

, , , Python pdb bdb ( " Python" ). , pdb. , , bdb " ", , ; pdb - , , .

IDE pdb , :

  • , .
  • IDE.

pdb.Pdb. , :

class MyPDB(pdb.Pdb):
    def __init__(self, breakpoints, completekey='tab',
                 stdin=None, stdout=None, skip=None):
        pdb.Pdb.__init__(self, completekey, stdin, stdout, skip)
        self._breakpoints = breakpoints

.pdbrc, pdb.Pdb.setup. , set_break, bdb.Bdb:

    def setInitialBreakpoints(self):
        _breakpoints = self._breakpoints
        self._breakpoints = None  # to avoid setting breaks twice
        for bp in _breakpoints:
            self.set_break(filename=bp.filename, line=bp.line,
                           temporary=bp.temporary, conditional=bp.conditional,
                           funcname=bp.funcname)

    def setup(self, f, t):
        pdb.Pdb.setup(self, f, t)
        self.setInitialBreakpoints()

, , . . bdb.Breakpoint, , , bdb.Bdb .

main , , pdb. - main pdb ( if __name__ == '__main__', ), , . IDE :

tmpfilename = ...
# write breakpoint info
p = subprocess.Popen(args=[sys.executable, '-m', 'mypdb', tmpfilename, ...], ...)
# delete the temporary file

mypdb.main() - :

def main():
    # code excerpted from pdb.main()
    ...
    del sys.argv[0]

    # add this
    bpfilename = sys.argv[0]
    with open(bpfilename) as f:
        # read breakpoint info
        breakpoints = ...
    del sys.argv[0]
    # back to excerpt from pdb.main()

    sys.path[0] = os.path.dirname(mainpyfile)

    pdb = Pdb(breakpoints) # modified

, pdb, , break . , Python , .

+7

All Articles