Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Pdb' object has no attribute 'botframe' #88627

Closed
jaraco opened this issue Jun 19, 2021 · 13 comments
Closed

'Pdb' object has no attribute 'botframe' #88627

jaraco opened this issue Jun 19, 2021 · 13 comments
Assignees
Labels
3.9 only security fixes 3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir

Comments

@jaraco
Copy link
Member

jaraco commented Jun 19, 2021

BPO 44461
Nosy @jaraco, @miss-islington, @iritkatriel
PRs
  • bpo-44461: Fix bug with pdb's handling of import error due to a packa… #26937
  • bpo-44461: Check early that a pdb target is valid for execution. #27227
  • [3.10] bpo-44461: Check early that a pdb target is valid for execution. (GH-27227) #27399
  • [3.9] bpo-44461: Check early that a pdb target is valid for execution. (GH-27227) #27400
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/jaraco'
    closed_at = <Date 2021-07-28.22:50:05.058>
    created_at = <Date 2021-06-19.15:55:24.546>
    labels = ['library', '3.9', '3.10', '3.11']
    title = "'Pdb' object has no attribute 'botframe'"
    updated_at = <Date 2021-07-28.22:50:05.057>
    user = 'https://github.com/jaraco'

    bugs.python.org fields:

    activity = <Date 2021-07-28.22:50:05.057>
    actor = 'jaraco'
    assignee = 'jaraco'
    closed = True
    closed_date = <Date 2021-07-28.22:50:05.058>
    closer = 'jaraco'
    components = ['Library (Lib)']
    creation = <Date 2021-06-19.15:55:24.546>
    creator = 'jaraco'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 44461
    keywords = ['patch']
    message_count = 13.0
    messages = ['396138', '396143', '396144', '396145', '396634', '396635', '396646', '396801', '396914', '398340', '398369', '398437', '398438']
    nosy_count = 3.0
    nosy_names = ['jaraco', 'miss-islington', 'iritkatriel']
    pr_nums = ['26937', '27227', '27399', '27400']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue44461'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    @jaraco
    Copy link
    Member Author

    jaraco commented Jun 19, 2021

    While doing some debugging on bpo-44459 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.

    @jaraco jaraco added 3.10 only security fixes stdlib Python modules in the Lib dir labels Jun 19, 2021
    @jaraco
    Copy link
    Member Author

    jaraco commented Jun 19, 2021

    I encountered the same error on Python 3.9.

    @jaraco jaraco added 3.9 only security fixes labels Jun 19, 2021
    @jaraco
    Copy link
    Member Author

    jaraco commented Jun 19, 2021

    I can replicate the issue with this command: python -m pdb -m importlib (since importlib isn't executable, it triggers an error in runpy).

    @jaraco
    Copy link
    Member Author

    jaraco commented Jun 19, 2021

    I was unable to replicate the issue with a foo.py containing only raise ValueError, even with python -m pdb -m foo.

    @iritkatriel
    Copy link
    Member

    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).

    @iritkatriel
    Copy link
    Member

    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.

    @iritkatriel iritkatriel added 3.11 only security fixes labels Jun 28, 2021
    @iritkatriel
    Copy link
    Member

    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.

    @jaraco
    Copy link
    Member Author

    jaraco commented Jun 30, 2021

    Thanks Irit. Reviewing now...

    @iritkatriel
    Copy link
    Member

    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)

    @jaraco
    Copy link
    Member Author

    jaraco commented Jul 28, 2021

    New changeset ee03bad by Jason R. Coombs in branch 'main':
    bpo-44461: Check early that a pdb target is valid for execution. (bpo-27227)
    ee03bad

    @miss-islington
    Copy link
    Contributor

    New changeset 684eb5c 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)
    684eb5c

    @jaraco
    Copy link
    Member Author

    jaraco commented Jul 28, 2021

    New changeset 49b5e20 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)
    49b5e20

    @jaraco
    Copy link
    Member Author

    jaraco commented Jul 28, 2021

    This issue is solved. Thanks Irit for taking the time to investigate the issue and do the hard part of developing a test.

    @jaraco jaraco closed this as completed Jul 28, 2021
    @jaraco jaraco closed this as completed Jul 28, 2021
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.9 only security fixes 3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants