classification
Title: pkgutil.get_loader and find_loader fail when module is missing
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.4, Python 3.5
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: brett.cannon Nosy List: Arfrever, Pavel.Aslanov, brett.cannon, eric.araujo, eric.snow, ncoghlan, python-dev
Priority: normal Keywords: patch

Created on 2012-05-03 10:45 by Pavel.Aslanov, last changed 2014-05-23 16:33 by brett.cannon. This issue is now closed.

Files
File name Uploaded Description Edit
python_pkgutil_bug.patch Pavel.Aslanov, 2012-05-03 10:45
Messages (9)
msg159848 - (view) Author: Pavel Aslanov (Pavel.Aslanov) Date: 2012-05-03 10:45
if module was marked as not existing by setting sys.modules [fullname] to None, then pkgutil.get_loader (fullname) will throw AttributeError.

Example:
#! /usr/bin/evn python
import unittest
import pkgutil

def main ():
    pkgutil.get_loader ('unittest.functools')

if __name__ == '__main__':
    main ()

Patch is attached
msg159861 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2012-05-03 15:19
So I'm no pkgutil expert, but at least in the case of None in sys.modules, that triggers at least an ImportError in __import__ if that is come across.
msg159900 - (view) Author: Pavel Aslanov (Pavel.Aslanov) Date: 2012-05-04 04:17
Main use case of pkgutil.get_loader is to determine if its possible to load module and either return loader or None. But it throws exception more over it is AttributeErrror exception.
msg159901 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2012-05-04 04:36
I'm not yet sure the proposed fix in the patch is the right approach (I need to look at the surrounding code), but I believe Pavel's right that get_loader() should be returning None in this case instead of throwing an exception.
msg215168 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-30 05:58
Update as of Python 3.4: pkgutil.get_loader() still throws AttributeError for this case, but importlib.util.find_spec() returns None as expected.
msg218789 - (view) Author: Pavel Aslanov (Pavel.Aslanov) Date: 2014-05-19 11:14
This function is broken again in version 3.4

The way it should look is:
Python 2.7.6 (default, Feb 26 2014, 12:07:17) 
[GCC 4.8.2 20140206 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkgutil
>>> pkgutil.get_loader('no_such_module') # returns None
>>> 

How it really looks:
Python 3.4.0 (default, Apr 27 2014, 23:33:09) 
[GCC 4.8.2 20140206 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkgutil
>>> pkgutil.get_loader('no_such_module')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/pkgutil.py", line 467, in get_loader
    return find_loader(fullname)
  File "/usr/lib/python3.4/pkgutil.py", line 488, in find_loader
    return spec.loader
AttributeError: 'NoneType' object has no attribute 'loader'
>>>

find_loader is at fault (change "return spec.loader" -> "return spec and spec.loader"). Thanks.
msg218803 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2014-05-19 17:46
I'll take a look the next time I have some Python time (in a week or two) and make sure this gets dealt with.
msg218977 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014-05-23 16:32
New changeset 660c82192c69 by Brett Cannon in branch '3.4':
Issue #14710: Fix both pkgutil.find_loader() and get_loader() to not
http://hg.python.org/cpython/rev/660c82192c69

New changeset 1adc8eb362f0 by Brett Cannon in branch 'default':
Merge for issue #14710
http://hg.python.org/cpython/rev/1adc8eb362f0
msg218978 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2014-05-23 16:33
Thanks for the bug report, Pavel. It turned out pkgutil.find_loader is broken as well as pkgutil.get_loader in different ways.
History
Date User Action Args
2014-05-23 16:33:33brett.cannonsetstatus: open -> closed

messages: + msg218978
stage: resolved
2014-05-23 16:32:42python-devsetnosy: + python-dev
messages: + msg218977
2014-05-23 16:27:59brett.cannonsetversions: - Python 2.7
2014-05-23 16:27:49brett.cannonsettitle: pkgutil.get_loader is broken -> pkgutil.get_loader and find_loader fail when module is missing
2014-05-19 19:07:59eric.snowsetnosy: + eric.snow
2014-05-19 17:46:34brett.cannonsetassignee: brett.cannon
messages: + msg218803
2014-05-19 11:14:37Pavel.Aslanovsetmessages: + msg218789
2014-03-30 05:58:01ncoghlansetmessages: + msg215168
versions: + Python 3.4, Python 3.5
2012-05-04 16:38:04eric.araujosetnosy: + eric.araujo
2012-05-04 04:41:48Arfreversetnosy: + Arfrever
2012-05-04 04:36:28ncoghlansetmessages: + msg159901
2012-05-04 04:17:18Pavel.Aslanovsetmessages: + msg159900
2012-05-03 15:19:27brett.cannonsetmessages: + msg159861
2012-05-03 10:54:44pitrousetnosy: + brett.cannon, ncoghlan
2012-05-03 10:45:40Pavel.Aslanovcreate