()
| 3587 | |
| 3588 | |
| 3589 | def parse_args(): |
| 3590 | # We want pdb to be as intuitive as possible to users, so we need to do some |
| 3591 | # heuristic parsing to deal with ambiguity. |
| 3592 | # For example: |
| 3593 | # "python -m pdb -m foo -p 1" should pass "-p 1" to "foo". |
| 3594 | # "python -m pdb foo.py -m bar" should pass "-m bar" to "foo.py". |
| 3595 | # "python -m pdb -m foo -m bar" should pass "-m bar" to "foo". |
| 3596 | # This require some customized parsing logic to find the actual debug target. |
| 3597 | |
| 3598 | import argparse |
| 3599 | |
| 3600 | parser = argparse.ArgumentParser( |
| 3601 | usage="%(prog)s [-h] [-c command] (-m module | -p pid | pyfile) [args ...]", |
| 3602 | description=_usage, |
| 3603 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| 3604 | allow_abbrev=False, |
| 3605 | color=True, |
| 3606 | ) |
| 3607 | |
| 3608 | # Get all the commands out first. For backwards compatibility, we allow |
| 3609 | # -c commands to be after the target. |
| 3610 | parser.add_argument('-c', '--command', action='append', default=[], metavar='command', dest='commands', |
| 3611 | help='pdb commands to execute as if given in a .pdbrc file') |
| 3612 | |
| 3613 | opts, args = parser.parse_known_args() |
| 3614 | |
| 3615 | if not args: |
| 3616 | # If no arguments were given (python -m pdb), print the whole help message. |
| 3617 | # Without this check, argparse would only complain about missing required arguments. |
| 3618 | # We need to add the arguments definitions here to get a proper help message. |
| 3619 | parser.add_argument('-m', metavar='module', dest='module') |
| 3620 | parser.add_argument('-p', '--pid', type=int, help="attach to the specified PID", default=None) |
| 3621 | parser.print_help() |
| 3622 | sys.exit(2) |
| 3623 | elif args[0] == '-p' or args[0] == '--pid': |
| 3624 | # Attach to a pid |
| 3625 | parser.add_argument('-p', '--pid', type=int, help="attach to the specified PID", default=None) |
| 3626 | opts, args = parser.parse_known_args() |
| 3627 | if args: |
| 3628 | # For --pid, any extra arguments are invalid. |
| 3629 | parser.error(f"unrecognized arguments: {' '.join(args)}") |
| 3630 | elif args[0] == '-m': |
| 3631 | # Debug a module, we only need the first -m module argument. |
| 3632 | # The rest is passed to the module itself. |
| 3633 | parser.add_argument('-m', metavar='module', dest='module') |
| 3634 | opt_module = parser.parse_args(args[:2]) |
| 3635 | opts.module = opt_module.module |
| 3636 | args = args[2:] |
| 3637 | elif args[0].startswith('-'): |
| 3638 | # Invalid argument before the script name. |
| 3639 | invalid_args = list(itertools.takewhile(lambda a: a.startswith('-'), args)) |
| 3640 | parser.error(f"unrecognized arguments: {' '.join(invalid_args)}") |
| 3641 | |
| 3642 | # Otherwise it's debugging a script and we already parsed all -c commands. |
| 3643 | |
| 3644 | return opts, args |
| 3645 | |
| 3646 | def main(): |
no test coverage detected
searching dependent graphs…