GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `pdb` consumes arguments greedily · Issue #135490 · python/cpython

pdb consumes arguments greedily #135490

New issue
Copy link
New issue
Copy link
Closed
Closed
pdb consumes arguments greedily#135490
Copy link
Assignees
gaogaotiantian
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@SnoopJ
SnoopJ
opened on Jun 13, 2025
Issue body actions

Bug report

Bug description:

I am reporting this bug on behalf of user Bradipo in #python on the Libera.chat IRC network. The user was trying to run a pytest quite with pdb and experiencing a confusing ImportError associated with the -m mark expression they were passing in.

It seems that the changes in 73ccfa2 (#109165) have changed the semantics of -m (and -c) so that any program being run with the debugger may not accept these arguments.

It is also worth mentioning that the traceback shown in the below reproduction does not manifest in the release build, which makes this problem harder to identify as there is no provenance for the error.

Reproduction

$ cat echo.py
import sys
print(sys.argv)
$ ./python -m pdb -m echo -m XYZ  # simulating running `pytest -m XYZ` with the debugger
Traceback (most recent call last):
  File "/home/jgerity/repos/cpython/Lib/pdb.py", line 166, in check
    self._details
  File "/home/jgerity/repos/cpython/Lib/functools.py", line 1014, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "/home/jgerity/repos/cpython/Lib/pdb.py", line 174, in _details
    return runpy._get_module_details(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen runpy>", line 142, in _get_module_details
ImportError: No module named XYZ
$ ./python -c "import sys; print(sys.version)"
3.13.0a0 (bisect/bad:73ccfa28c5e, Jun 13 2025, 18:26:14) [GCC 12.3.0]

Expected behavior:

$ ./python -m pdb -m echo -m XYZ  # pdb prompt available at startup, -m in sys.argv
> /home/jgerity/repos/cpython/echo.py(1)<module>()
-> import sys
(Pdb) continue
['echo', '-m', 'XYZ']
The program finished and will be restarted
> /home/jgerity/repos/cpython/echo.py(1)<module>()
-> import sys
(Pdb) quit
$ ./python -c "import sys; print(sys.version)"  # AKA 73ccfa2~1
3.13.0a0 (tags/v3.12.0b1-1758-g3e8fcb7df74:3e8fcb7df74, Jun 13 2025, 18:32:54) [GCC 12.3.0]

with thanks to @nedbat for the excellent suggestion to use echo.py to cut pytest out of the reproduction.

CPython versions tested on:

3.13, 3.12

Operating systems tested on:

Linux

Linked PRs

  • gh-135490: Add warning about arguments that conflict with pdb #135520

Activity

  1. SnoopJ
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Jun 13, 2025
  2. picnixz
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Jun 13, 2025
  3. SnoopJ commented on Jun 13, 2025

    @SnoopJ
    SnoopJ
    on Jun 13, 2025
    ContributorAuthor
    More actions

    I should note that this problem does also manifest for ./python -m pdb echo.py -m XYZ

  4. gaogaotiantian commented on Jun 13, 2025

    @gaogaotiantian
    gaogaotiantian
    on Jun 13, 2025
    Member
    More actions

    Okay so this is a side effect of moving to argparse. To be honest I think this is a bug (that we probably can't fix) of argparse. The fundamental issue here is that the user passes two -m arguments to pdb, and expects the second one to be automatically considered as the argument to the program being debugged. Even though this is kind of user-intuitive, argparse does not deal with it well. When it is fed two -m, it will just use the latter one (instead of raising an error).

    We can probably do something for it to re-select the first one, we already have some special logic for it.

    The second case ./python -m pdb echo.py -m XYZ is a bit different - it's actually more ambiguous. I agree that it's not backwards compatible with 3.12, but I'm not entirely convinced that this is supposed to work.

    I think a general rule of thumb is - if you are trying to pass an ambiguous argument (that both pdb and the script/module can parse), you should separate those with --. So ./python -m pdb echo.py -- -m XYZ is a proper way to debug.

  5. SnoopJ commented on Jun 13, 2025

    @SnoopJ
    SnoopJ
    on Jun 13, 2025
    ContributorAuthor
    More actions

    Hrm, I could have sworn I tried adding -- between the module and the args during our discussion on IRC and it didn't work. I must have been doing something wrong, that does resolve this problem.

    To be honest I think this is a bug (that we probably can't fix) of argparse

    I can see potential for a workaround by injecting -- from pdb but maybe that is too much of a kludge. Maybe this is in the direction you mean when you talk about "re-select the first one"?

  6. gaogaotiantian commented on Jun 13, 2025

    @gaogaotiantian
    gaogaotiantian
    on Jun 13, 2025
    Member
    More actions

    The effort would be when -m exists, do a lot of manual parse to make it intuitive (and backward compatible). The existing CLI arguments of pdb is relatively simple now so we can kind of do this, but I'm not sure if that's very maintainable in the future. I think it's safest for the user to explicitly separate the arguments with --. However, at this point, I'll see if I can work something out. I don't want to re-write a parser.

    It should work work with -m echo - ./python -m pdb -m echo -- -m XYZ

  7. SnoopJ commented on Jun 13, 2025

    @SnoopJ
    SnoopJ
    on Jun 13, 2025
    ContributorAuthor
    More actions

    Understood. I'll write up a docs PR to add a warning to the pdb docs to at least give users a fighting chance to know that this sharp edge has been introduced. Edit: see #135520

    As an alternative to the maintenance burden that a "true fix" would create, do you think it's feasible to try and detect the case of multiple -m before calling into argparse and issue a suitable warning/error? This seems like it could be a workable compromise position that balances the complexity of the fix against the relatively unmovable nature of the problem.

  8. gaogaotiantian commented on Jun 13, 2025

    @gaogaotiantian
    gaogaotiantian
    on Jun 13, 2025
    Member
    More actions

    Let me take a look at the problem and see if we can find a reasonable fix - as we already have some manual parsing in pdb now. If we can make this work with understandable code, we can do that.

    Reacted by James
  9. SnoopJ commented on Jun 13, 2025

    @SnoopJ
    SnoopJ
    on Jun 13, 2025
    ContributorAuthor
    More actions

    Thanks. In the meantime, here's a failing test of the -m echo form.

    diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
    index 6b74e21ad73..b37f88db620 100644
    --- a/Lib/test/test_pdb.py
    +++ b/Lib/test/test_pdb.py
    @@ -3995,6 +3995,34 @@ def test_run_script_with_args(self):
             stdout, stderr = self.run_pdb_script(script, commands, script_args=["--bar", "foo"])
             self.assertIn("['--bar', 'foo']", stdout)
     
    +    def test_run_module_with_m_arg(self):
    +        """See GH-135490
    +
    +        Check that pdb can run a module which accepts -m as an argument
    +        """
    +        script = """
    +            import sys
    +            print(sys.argv)
    +        """
    +        commands = """
    +            continue
    +            quit
    +        """
    +
    +        module_name = 'gh135490_echo'
    +        os_helper.rmtree(module_name)
    +        init_file = module_name + '/__main__.py'
    +        os.mkdir(module_name)
    +
    +        with open(init_file, 'w') as f:
    +            f.write(script)
    +
    +        self.addCleanup(os_helper.rmtree, module_name)
    +        stdout, stderr = self._run_pdb(
    +            ['-m', module_name, '-m', 'XYZ'], commands
    +        )
    +        self.assertIn("['-m', 'XYZ']", stdout)
    +
         def test_breakpoint(self):
             script = """
                 if __name__ == '__main__':
    
  10. gaogaotiantian
    self-assigned this
    on Jun 14, 2025
  11. SnoopJ commented on Oct 20, 2026

    @SnoopJ
    SnoopJ
    on Oct 20, 2026
    ContributorAuthor
    More actions

    After revisiting #135520 (because it was taking up a slot in the newly-introduced contributor PR limit), this issue applies only to Python 3.13 (3.13.16 is impacted), the issue is not present in 3.12, 3.14, 3.15.

    I haven't bothered to track down the changeset that restored the expected behavior, but this issue is now only useful to note that the bug exists since 3.13 has entered its security window and the fix would not be backported anyway. Closing.

  12. SnoopJ
    closed this as completedon Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @gaogaotiantian
    gaogaotiantian

Labels

stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.