Message338028
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). |
|
Date |
User |
Action |
Args |
2019-03-15 20:28:38 | terry.reedy | set | recipients:
+ terry.reedy, brett.cannon, mental |
2019-03-15 20:28:38 | terry.reedy | set | messageid: <1552681718.22.0.812015193836.issue36298@roundup.psfhosted.org> |
2019-03-15 20:28:38 | terry.reedy | link | issue36298 messages |
2019-03-15 20:28:38 | terry.reedy | create | |
|