Closed
Description
Bug report
Checklist
- I am confident this is a bug in CPython, not a bug in a third-party project
- I have searched the CPython issue tracker,
and am confident this bug has not been reported before
CPython versions tested on:
3.11, 3.12, CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.13.0a0 (heads/main:578ebc5d5f, Sep 1 2023, 20:48:35) [GCC 10.2.1 20210110]
A clear and concise description of the bug:
pdb
module produces large traceback instead of short error message if invoked with invalid command line option. This happens because it doesn't handle exceptions that can occur in getopt.getopt
, as it typically done.
$ ./python -m pdb -c Traceback (most recent call last): File "/home/radislav/projects/cpython/Lib/runpy.py", line 198, in _run_module_as_main return _run_code(code, main_globals, None, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/runpy.py", line 88, in _run_code exec(code, run_globals) File "/home/radislav/projects/cpython/Lib/pdb.py", line 2114, in <module> pdb.main() File "/home/radislav/projects/cpython/Lib/pdb.py", line 2060, in main opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['help', 'command=']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/getopt.py", line 95, in getopt opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/getopt.py", line 198, in do_shorts raise GetoptError(_('option -%s requires argument') % opt, getopt.GetoptError: option -c requires argument
A similar situation is with nonexistant modules and directory names. In the first case an exception that occurs in _ModuleTarget.check
is printed to stderr with its traceback. In the second case directory name is 'successfully' checked by _ScriptTarget.check
call, and debugger is ran on invalid target.
$ ./python -m pdb -m spam Traceback (most recent call last): File "/home/radislav/projects/cpython/Lib/pdb.py", line 166, in check self._details File "/home/radislav/projects/cpython/Lib/functools.py", line 1014, in __get__ val = self.func(instance) ^^^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/pdb.py", line 174, in _details return runpy._get_module_details(self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/runpy.py", line 142, in _get_module_details raise error("No module named %s" % mod_name) ImportError: No module named spam
$ ./python -m pdb / Traceback (most recent call last): File "/home/radislav/projects/cpython/Lib/pdb.py", line 2088, in main pdb._run(target) File "/home/radislav/projects/cpython/Lib/pdb.py", line 1868, in _run self.run(target.code) ^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/pdb.py", line 159, in code with io.open_code(self) as fp: ^^^^^^^^^^^^^^^^^^ IsADirectoryError: [Errno 21] Is a directory: '/' Uncaught exception. Entering post mortem debugging Running 'cont' or 'step' will restart the program > /home/radislav/projects/cpython/Lib/pdb.py(159)code() -> with io.open_code(self) as fp: (Pdb) c Traceback (most recent call last): File "/home/radislav/projects/cpython/Lib/pdb.py", line 2088, in main pdb._run(target) File "/home/radislav/projects/cpython/Lib/pdb.py", line 1868, in _run self.run(target.code) ^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/pdb.py", line 159, in code with io.open_code(self) as fp: ^^^^^^^^^^^^^^^^^^ IsADirectoryError: [Errno 21] Is a directory: '/' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/radislav/projects/cpython/Lib/runpy.py", line 198, in _run_module_as_main return _run_code(code, main_globals, None, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/runpy.py", line 88, in _run_code exec(code, run_globals) File "/home/radislav/projects/cpython/Lib/pdb.py", line 2114, in <module> pdb.main() File "/home/radislav/projects/cpython/Lib/pdb.py", line 2106, in main pdb.interaction(None, e) File "/home/radislav/projects/cpython/Lib/pdb.py", line 501, in interaction self._cmdloop() File "/home/radislav/projects/cpython/Lib/pdb.py", line 405, in _cmdloop self.cmdloop() File "/home/radislav/projects/cpython/Lib/cmd.py", line 138, in cmdloop stop = self.onecmd(line) ^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/pdb.py", line 592, in onecmd return cmd.Cmd.onecmd(self, line) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/cmd.py", line 217, in onecmd return func(arg) ^^^^^^^^^ File "/home/radislav/projects/cpython/Lib/pdb.py", line 1329, in do_continue self.set_continue() File "/home/radislav/projects/cpython/Lib/bdb.py", line 344, in set_continue self._set_stopinfo(self.botframe, None, -1) ^^^^^^^^^^^^^ AttributeError: 'Pdb' object has no attribute 'botframe'. Did you mean: 'curframe'?
I'm working on a fix.
Linked PRs
- gh-108791: Fix
pdb
CLI invalid argument handling #108816 - [3.12] gh-108791: Fix
pdb
CLI invalid argument handling (GH-108816) #110915 - [3.11] gh-108791: Fix
pdb
CLI invalid argument handling (GH-108816) #110916 - [3.11] gh-108791: Fix pdb CLI invalid argument handling (GH-108816) #111063
- [3.12] gh-108791: Fix pdb CLI invalid argument handling (GH-108816) #111064