classification
Title: 'Pdb' object has no attribute 'botframe'
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: jaraco Nosy List: iritkatriel, jaraco, miss-islington
Priority: normal Keywords: patch

Created on 2021-06-19 15:55 by jaraco, last changed 2021-07-28 22:50 by jaraco. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 26937 closed iritkatriel, 2021-06-28 16:11
PR 27227 merged jaraco, 2021-07-18 13:47
PR 27399 merged jaraco, 2021-07-28 01:59
PR 27400 merged jaraco, 2021-07-28 02:02
Messages (13)
msg396138 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-06-19 15:55
While doing some debugging on issue44459 using Python 3.10b3, I was using Pdb and after troubleshooting an exception and hitting 'q' to quit, I saw the following:

```
(Pdb) q
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 1709, in main
    pdb._runmodule(mainpyfile)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 1541, in _runmodule
    mod_name, mod_spec, code = runpy._get_module_details(module_name)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 146, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 110, in _get_module_details
    __import__(pkg_name)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-w0xovt3h/rinoh/__init__.py", line 41, in <module>
    from . import resource
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-w0xovt3h/rinoh/resource.py", line 205, in <module>
    from .template import DocumentTemplate
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-w0xovt3h/rinoh/template.py", line 42, in <module>
    from .stylesheets import sphinx
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-w0xovt3h/rinoh/stylesheets/__init__.py", line 42, in <module>
    .format(stylesheet.description, stylesheet))
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-w0xovt3h/rinoh/style.py", line 670, in __str__
    for name, entry_point in self.installed_resources:
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-w0xovt3h/rinoh/resource.py", line 54, in installed_resources
    for entry_point in ilm.entry_points()[cls.entry_point_group]:
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/metadata/__init__.py", line 979, in entry_points
    return SelectableGroups.load(eps).select(**params)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/metadata/__init__.py", line 437, in load
    ordered = sorted(eps, key=by_group)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/metadata/__init__.py", line -1, in <genexpr>
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/metadata/_itertools.py", line 16, in unique_everseen
    k = key(element)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/metadata/__init__.py", line 600, in _normalized_name
    return Prepared.normalize(self.name)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/metadata/__init__.py", line 841, in normalize
    return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_')
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/re.py", line 187, in sub
    return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or bytes-like object

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 1738, in <module>
    pdb.main()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 1730, in main
    pdb.interaction(None, t)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 357, in interaction
    self._cmdloop()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 322, in _cmdloop
    self.cmdloop()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/cmd.py", line 138, in cmdloop
    stop = self.onecmd(line)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 422, in onecmd
    return cmd.Cmd.onecmd(self, line)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/cmd.py", line 217, in onecmd
    return func(arg)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pdb.py", line 1118, in do_quit
    self.set_quit()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/bdb.py", line 358, in set_quit
    self.stopframe = self.botframe
AttributeError: 'Pdb' object has no attribute 'botframe'. Did you mean: 'curframe'?
```

I'd not seen this error before, so I suspect there may be a regression in 3.10. I haven't investigated further, but I wanted to register this possible issue.
msg396143 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-06-19 17:08
I encountered the same error on Python 3.9.
msg396144 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-06-19 17:10
I can replicate the issue with this command: `python -m pdb -m importlib` (since `importlib` isn't executable, it triggers an error in runpy).
msg396145 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-06-19 17:18
I was _unable_ to replicate the issue with a foo.py containing only `raise ValueError`, even with `python -m pdb -m foo`.
msg396634 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-06-28 13:21
The difference between Jason's two test cases is which stage of Pdb._runmodule() fails. 

In the case of `python -m pdb -m importlib` runpy._get_module_details(module_name) raises an exception because importlib is a package and it looks for its __main__, so self.run(code) is never called.

In the case of `python -m pdb -m foo` with foo that raises an exception,  foo is not a package so the __main__ check doesn't happen. The exception comes from within the self.run(code) call (when the module is executed). self.run() calls self.reset() before executing the code, and reset() calls Bdb.reset() which initializes self.botframe (to None).
msg396635 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-06-28 13:22
However, if we just try to initialize self.botframe to None in __init__, then 'quit' doesn't work anymore, so something else needs to be done about cleanup when import fails at that stage.
msg396646 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-06-28 16:22
The cleanup issue was in the except: clause of the main loop: if the user does quit() during the pdb.interaction() call upon an unhandled exception ("the post mortem debugger"), then this quit request is ignored and the program just restarts.

The attached patch fixes this by checking for quit requests after the port-mortem debugger returns.
msg396801 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-06-30 21:43
Thanks Irit. Reviewing now...
msg396914 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-07-03 16:32
I've close PR26937 since we're not going for that. The test from it might still be useful, so I'm copying it here:

    def test_package_without_a_main(self):
        pkg_name = 't_pkg'
        module_name = 't_main'
        os_helper.rmtree(pkg_name)
        modpath = pkg_name + '/' + module_name
        os.makedirs(modpath)
        with open(modpath + '/__init__.py', 'w') as f:
            pass
        self.addCleanup(os_helper.rmtree, pkg_name)
        stdout, stderr = self._run_pdb(['-m', modpath.replace('/', '.')], "")
        self.assertIn(
            "'t_pkg.t_main' is a package and cannot be directly executed",
            stdout)
msg398340 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-07-28 01:52
New changeset ee03bad25e83b00ba5fc2a0265b48c6286e6b3f7 by Jason R. Coombs in branch 'main':
bpo-44461: Check early that a pdb target is valid for execution. (#27227)
https://github.com/python/cpython/commit/ee03bad25e83b00ba5fc2a0265b48c6286e6b3f7
msg398369 - (view) Author: miss-islington (miss-islington) Date: 2021-07-28 13:04
New changeset 684eb5cb8016546f1f8652dae8febd5c6571193e by Jason R. Coombs in branch '3.10':
[3.10] bpo-44461: Check early that a pdb target is valid for execution. (GH-27227) (GH-27399)
https://github.com/python/cpython/commit/684eb5cb8016546f1f8652dae8febd5c6571193e
msg398437 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-07-28 22:48
New changeset 49b5e20fa8c091f9158ccd26f9a12fc1e91cfc93 by Jason R. Coombs in branch '3.9':
[3.9] bpo-44461: Check early that a pdb target is valid for execution. (GH-27227) (GH-27400)
https://github.com/python/cpython/commit/49b5e20fa8c091f9158ccd26f9a12fc1e91cfc93
msg398438 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-07-28 22:50
This issue is solved. Thanks Irit for taking the time to investigate the issue and do the hard part of developing a test.
History
Date User Action Args
2021-07-28 22:50:05jaracosetstatus: open -> closed
resolution: fixed
messages: + msg398438

stage: patch review -> resolved
2021-07-28 22:48:57jaracosetmessages: + msg398437
2021-07-28 13:04:50miss-islingtonsetnosy: + miss-islington
messages: + msg398369
2021-07-28 02:02:36jaracosetpull_requests: + pull_request25933
2021-07-28 01:59:37jaracosetpull_requests: + pull_request25932
2021-07-28 01:52:10jaracosetmessages: + msg398340
2021-07-18 14:27:25jaracosetpull_requests: - pull_request25553
2021-07-18 13:47:56jaracosetpull_requests: + pull_request25768
2021-07-03 16:32:32iritkatrielsetmessages: + msg396914
2021-07-02 13:26:04jaracosetpull_requests: + pull_request25553
2021-06-30 21:43:47jaracosetassignee: jaraco
messages: + msg396801
2021-06-28 16:22:41iritkatrielsetmessages: + msg396646
2021-06-28 16:11:57iritkatrielsetkeywords: + patch
stage: patch review
pull_requests: + pull_request25506
2021-06-28 13:22:39iritkatrielsetmessages: + msg396635
versions: + Python 3.11
2021-06-28 13:21:23iritkatrielsetnosy: + iritkatriel
messages: + msg396634
2021-06-19 17:18:42jaracosetkeywords: - 3.10regression
2021-06-19 17:18:31jaracosetmessages: + msg396145
2021-06-19 17:10:11jaracosetmessages: + msg396144
2021-06-19 17:08:19jaracosetmessages: + msg396143
versions: + Python 3.9
2021-06-19 15:55:24jaracocreate