DKNUCKLES DKNUCKLES - 2 months ago 28
Python Question

Error when using importlib.util to check for library

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

Answer

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.