Navigation Menu

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

Lib/pyclbr.py crashes when the package spec cannot be determined by importlib #80479

Closed
mental32 mannequin opened this issue Mar 15, 2019 · 8 comments
Closed

Lib/pyclbr.py crashes when the package spec cannot be determined by importlib #80479

mental32 mannequin opened this issue Mar 15, 2019 · 8 comments
Assignees
Labels
3.7 (EOL) end of life stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@mental32
Copy link
Mannequin

mental32 mannequin commented Mar 15, 2019

BPO 36298
Nosy @brettcannon, @miss-islington, @mental32
PRs
  • bpo-36298: Raise ModuleNotFoundError in pyclbr when a module can't be found #12358
  • 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/brettcannon'
    closed_at = <Date 2019-03-25.18:15:15.299>
    created_at = <Date 2019-03-15.05:43:26.842>
    labels = ['3.7', 'type-bug', 'library']
    title = 'Lib/pyclbr.py crashes when the package spec cannot be determined by importlib'
    updated_at = <Date 2019-03-25.18:15:15.298>
    user = 'https://github.com/mental32'

    bugs.python.org fields:

    activity = <Date 2019-03-25.18:15:15.298>
    actor = 'brett.cannon'
    assignee = 'brett.cannon'
    closed = True
    closed_date = <Date 2019-03-25.18:15:15.299>
    closer = 'brett.cannon'
    components = ['Library (Lib)']
    creation = <Date 2019-03-15.05:43:26.842>
    creator = 'mental'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 36298
    keywords = ['patch']
    message_count = 8.0
    messages = ['337966', '338028', '338032', '338034', '338037', '338094', '338618', '338817']
    nosy_count = 3.0
    nosy_names = ['brett.cannon', 'miss-islington', 'mental']
    pr_nums = ['12358']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue36298'
    versions = ['Python 3.7']

    @mental32
    Copy link
    Mannequin Author

    mental32 mannequin commented Mar 15, 2019

    Hi folks! (apologies in advance if any of the code blocks come out irregular, this is my first issue)

    I was just exploring the Lib modules out of curiosity and I discovered pyclbr a peculiar artifact from the older days of the Python standard library.

    I noticed the module could be run directly and after attempting to run it withan invalid source target python -m pyclbr somenonexistentfile it raised Traceback (most recent call last): File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "/usr/lib/python3.7/runpy.py", line 85, in _run_code exec(code, run_globals) File "/usr/lib/python3.7/pyclbr.py", line 405, in <module> _main() File "/usr/lib/python3.7/pyclbr.py", line 380, in _main tree = readmodule_ex(mod, path) File "/usr/lib/python3.7/pyclbr.py", line 116, in readmodule_ex return _readmodule(module, path or []) File "/usr/lib/python3.7/pyclbr.py", line 169, in _readmodule if spec.submodule_search_locations is not None: AttributeError: 'NoneType' object has no attribute 'submodule_search_locations'

    I was running 3.7.2, although I assume this affects future versions and possibly some older versions. (I suspect the bug originates from importlib silently breaking backwards compatability)

    I thought it strange for a script to exit so loudly so after reading through the source I believe the intended behavior meant for an invalid target is to raise an ImportError although I admit I'm not convinced this is still the best way to exit from erroneous input (or even if the module is still relevant in todays code?)

    I believe this is a bug (but I would very much appreciate a second opinion) and I've identified it as a low priority easy fix, In which case I'd be more than happy to submit a fix :)

    @mental32 mental32 mannequin added type-crash A hard crash of the interpreter, possibly with a core dump 3.7 (EOL) end of life type-bug An unexpected behavior, bug, or error and removed type-crash A hard crash of the interpreter, possibly with a core dump labels Mar 15, 2019
    @SilentGhost SilentGhost mannequin added the stdlib Python modules in the Lib dir label Mar 15, 2019
    @terryjreedy
    Copy link
    Member

    I finished patching pyclbr to be a complete module class and function browser in summer 2017, for use by IDLE's class browser.

    I verified the bug with the import API, with a twist.

    >>> import pyclbr
    >>> pyclbr.readmodule_ex('<invalid')
    ...
    AttributeError: 'NoneType' object has no attribute 'submodule_search_locations'
    >>> pyclbr.readmodule_ex('<invalid>')
    {}

    The relevant block in pyclbr is

        spec = importlib.util._find_spec_from_path(fullmodule, search_path)
        _modules[fullmodule] = tree
        # Is module a package?
        if spec.submodule_search_locations is not None:
            tree['__path__'] = spec.submodule_search_locations

    Caching (fullmodule, tree) before the spec access is why the repeat call above returns the empty tree.

    This block is preceded by a block that explicitly raises 'ImportError', even though no import is attemped. It is followed by a block that returns the tree in case of error.

    try:
        source = spec.loader.get_source(fullmodule)
        if source is None:
            return tree
    except (AttributeError, ImportError):
        # If module is not Python source, we cannot do anything.
        return tree
    

    So either a) the empty tree should be returned when the NoneType exception is caught, or b) the invalid names should not be cached and the AttributeError turned into an 'ImportError'.

    I believe we should do the latter, as you suggested, and move the caching line down to follow the new try-except. If you want, submit a PR for the master branch *after* signing the CLA. If you can, include a new assertRaises test based on the invalid call above. And check that '<invalid>' is not in pyclbr._modules with assertNotIn('<invalid>', pyclbr._modules).

    @terryjreedy terryjreedy added the 3.8 only security fixes label Mar 15, 2019
    @terryjreedy terryjreedy self-assigned this Mar 15, 2019
    @terryjreedy terryjreedy changed the title Lib/pyclbr.py crashes when the package spec cannot be determined by importlib Lib/pyclbr.py fails when package spec cannot be determined Mar 15, 2019
    @brettcannon brettcannon removed the 3.8 only security fixes label Mar 15, 2019
    @brettcannon brettcannon changed the title Lib/pyclbr.py fails when package spec cannot be determined Lib/pyclbr.py crashes when the package spec cannot be determined by importlib Mar 15, 2019
    @brettcannon
    Copy link
    Member

    I have a fix en-route.

    @brettcannon
    Copy link
    Member

    Got a patch up if either of you would like to review.

    @brettcannon
    Copy link
    Member

    (And sorry about stealing this from you, Terry; I forgot to flip the assignment while I was looking into this.)

    @mental32
    Copy link
    Mannequin Author

    mental32 mannequin commented Mar 16, 2019

    Thanks :) I've submitted a review for the patch.

    @miss-islington
    Copy link
    Contributor

    New changeset 5086589 by Miss Islington (bot) (Brett Cannon) in branch 'master':
    bpo-36298: Raise ModuleNotFoundError in pyclbr when a module can't be found (GH-12358)
    5086589

    @brettcannon
    Copy link
    Member

    Thanks, mental!

    @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.7 (EOL) end of life stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants