How to debug a Python module run with python -m from the command line?

后端 未结 6 548
后悔当初
后悔当初 2020-12-09 15:20

I know that a Python script can be debugged from the command line with

python -m pdb my_script.py

if my_script.py is a script

6条回答
  •  猫巷女王i
    2020-12-09 16:05

    The following script will run a module and break into post-mortem debugging if an exception occurs while running the module. It should work both with Python 2.7 and 3.x.

    Usage:

    mdb.py module_name [args ...]
    

    Known limitations:

    • While running the module code, sys.argv[0] is preserved as the module name, instead of being resolved to the file path of the module.
    • If the target module is not found, the error is not reported any differently than if the error occurred during the execution of the module

    mdb.py

    #!/usr/bin/env python
    
    from __future__ import print_function
    import pdb
    import runpy
    import sys
    import traceback
    
    if len(sys.argv) == 0:
        print("Usage: mdb.py module_name [args ...]")
        exit(1)
    
    modulename = sys.argv[1]
    del sys.argv[0]
    
    try:
        runpy.run_module(modulename, run_name='__main__')
    except:
        traceback.print_exception(*sys.exc_info())
        print("")
        print("-" * 40)
        print("mdb: An exception occurred while executing module ", modulename)
        print("mdb: See the traceback above.")
        print("mdb: Entering post-mortem debugging.")
        print("-" * 40)
        pdb.post_mortem(sys.exc_info()[2])
    

    Demonstration:

    $ tree
    .
    ├── mdb.py
    └── mypackage
        ├── __init__.py
        ├── __main__.py
        └── mymodule.py
    
    1 directory, 4 files
    
    $ ###################### Examine the module code ###################
    $ cat mypackage/mymodule.py 
    from __future__ import print_function
    import sys
    
    print("mymodule loaded")
    
    if __name__ == "__main__":
        print("mymodule executed")
        print("args:", sys.argv)
    
    $ #################### Run the module through python ###############
    $ python -m mypackage.mymodule abc defgh
    mymodule loaded
    mymodule executed
    args: ['/home/leon/playground/mdb/mypackage/mymodule.py', 'abc', 'defgh']
    
    $ #################### Run the module through mdb ##################
    $ ./mdb.py mypackage.mymodule abc defgh
    mymodule loaded
    mymodule executed
    args: ['mypackage.mymodule', 'abc', 'defgh']
    $ ###   ^^^^^^^^^^^^^^^^^^
    $ ### Note that sys.argv[0] is not resolved to the file path
    
    $ ###################### Examine the module code ###################
    $ cat mypackage/__main__.py 
    from __future__ import print_function
    import sys
    
    print("mypackage loaded")
    
    if __name__ == "__main__":
        print("mypackage executed")
        print("args:", sys.argv)
        print(x + y)
    
    $ #################### Run the module through python ###############
    $ python -m mypackage
    mypackage loaded
    mypackage executed
    args: ['/home/leon/playground/mdb/mypackage/__main__.py']
    Traceback (most recent call last):
      File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
        "__main__", fname, loader, pkg_name)
      File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
        exec code in run_globals
      File "/home/leon/playground/mdb/mypackage/__main__.py", line 9, in 
        print(x + y)
    NameError: name 'x' is not defined
    
    $ #################### Run the module through mdb ##################
    $ ./mdb.py mypackage
    mypackage loaded
    mypackage executed
    args: ['mypackage']
    Traceback (most recent call last):
      File "./mdb.py", line 17, in 
        runpy.run_module(modulename, run_name='__main__')
      File "/usr/lib/python2.7/runpy.py", line 192, in run_module
        fname, loader, pkg_name)
      File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
        exec code in run_globals
      File "/home/leon/playground/mdb/mypackage/__main__.py", line 9, in 
        print(x + y)
    NameError: name 'x' is not defined
    
    ----------------------------------------
    mdb: An exception occurred while executing module  mypackage
    mdb: See the traceback above.
    mdb: Entering post-mortem debugging.
    ----------------------------------------
    > /home/leon/playground/mdb/mypackage/__main__.py(9)()
    -> print(x + y)
    (Pdb) q
    

提交回复
热议问题