Error when using importlib.util to check for library
python, python-3.x, python-importlib
Solution
Try this:
from importlib import util
util.find_spec("nmap")
I intend to investigate, but honestly I don't know why one works and the other doesn't. Also, observe the following interactive session:
>>> import importlib
>>> importlib.util
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'
>>> from importlib import util
>>> util
<module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'>
>>> importlib.util
<module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'>
So...yeah. I am sure this makes perfect sense to someone, but not to me. I will update once I figure it out.
Update:
Comparing this to something like:
>>> import datetime
>>> datetime
<module 'datetime' from '/usr/lib/python3.5/datetime.py'>
>>> datetime.datetime
<class 'datetime.datetime'>
I think the difference is that in this case the first `datetime` is a module and the second is a class, while in the `importlib.util` case both are modules. So perhaps `module.module` is not OK unless the code from both modules has been loaded, while `module.class` is OK, because the class code is loaded when the module is imported.
Update #2
Nope, it seems like in many cases `module.module` is fine. For example:
>>> import urllib
>>> urllib
<module 'urllib' from '/usr/lib/python3.5/urllib/__init__.py'>
>>> urllib.error
<module 'urllib.error' from '/usr/lib/python3.5/urllib/error.py'>
So perhaps it is something specific to `importlib`.
Update #3
As @kfb pointed out in the comments, it does seem to be related to `importlib` specifically. See the following comment from the `__init__.py` for `importlib`:
# Until bootstrapping is complete, DO NOT import any modules that attempt
# to import importlib._bootstrap (directly or indirectly). Since this
# partially initialised package would be present in sys.modules, those
# modules would get an uninitialised copy of the source version, instead
# of a fully initialised version (either the frozen one or the one
# initialised below if the frozen one is not available).
`importlib/util.py` does import `importlib._bootstrap` so I would assume that this is realted. If my understanding is correct, when you do `import importlib` the submodules will be initialized, but are not initialized for the `importlib` module object that you have imported. At this point, if you do `dir(importlib)` you will not see `util`. Interestingly, after you have tried to access `importlib.util` and gotten an `AttributeError`, `util` (along with the other submodules) gets loaded/initialized, and now you can access `importlib.util`!
>>> import importlib
>>> dir(importlib)
['_RELOADING', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__import__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_bootstrap', '_bootstrap_external', '_imp', '_r_long', '_w_long', 'find_loader', 'import_module', 'invalidate_caches', 'reload', 'sys', 'types', 'warnings']
>>> importlib.util
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'
>>> importlib.util
<module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'>
>>> dir(importlib)
['_RELOADING', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__import__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_bootstrap', '_bootstrap_external', '_imp', '_r_long', '_w_long', 'abc', 'find_loader', 'import_module', 'invalidate_caches', 'machinery', 'reload', 'sys', 'types', 'util', 'warnings']
Problem
I'm trying to use the importlib library to verify whether the nmap library is installed on the computer executing the script in Python 3.5.2 I'm trying to use `importlib.util.find_spec("nmap")` but receive the following error. ``` >>> import importlib >>> importlib.util.find_spec("nmap") Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'importlib' has no attribute 'util' ``` Can someone tell me where I'm going wrong? EDIT I was able to get the function to work using the following code. ``` #!/usr/bin/pythonw import importlib from importlib import util #check to see if nmap module is installed find_nmap = util.find_spec("nmap") if find_nmap is None: print("Error") ```