Error when using importlib.util to check for library
<p>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</p>

<p>I'm trying to use <code>importlib.util.find_spec("nmap")</code> but receive the following error.</p>

<pre><code>&gt;&gt;&gt; import importlib
&gt;&gt;&gt; importlib.util.find_spec("nmap")
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
AttributeError: module 'importlib' has no attribute 'util'
</code></pre>

<p>Can someone tell me where I'm going wrong?</p>

<p><strong>EDIT</strong></p>

<p>I was able to get the function to work using the following code.</p>

<pre><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")
</code></pre>

<p>Try this:</p>

<pre><code>from importlib import util
util.find_spec("nmap")
</code></pre>

<p>I intend to investigate, but honestly I don't know why one works and the other doesn't. Also, observe the following interactive session:</p>

<pre><code>&gt;&gt;&gt; import importlib
&gt;&gt;&gt; importlib.util
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
AttributeError: module 'importlib' has no attribute 'util'
&gt;&gt;&gt; from importlib import util
&gt;&gt;&gt; util
&lt;module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'&gt;
&gt;&gt;&gt; importlib.util
&lt;module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'&gt;
</code></pre>

<p>So...yeah. I am sure this makes perfect sense to someone, but not to me. I will update once I figure it out.</p>

<h1>Update:</h1>

<p>Comparing this to something like:</p>

<pre><code>&gt;&gt;&gt; import datetime
&gt;&gt;&gt; datetime
&lt;module 'datetime' from '/usr/lib/python3.5/datetime.py'&gt;
&gt;&gt;&gt; datetime.datetime
&lt;class 'datetime.datetime'&gt;
</code></pre>

<p>I think the difference is that in this case the first <code>datetime</code> is a module and the second is a class, while in the <code>importlib.util</code> case both are modules. So perhaps <code>module.module</code> is not OK unless the code from both modules has been loaded, while <code>module.class</code> is OK, because the class code is loaded when the module is imported.</p>

<h1>Update #2</h1>

<p>Nope, it seems like in many cases <code>module.module</code> is fine. For example:</p>

<pre><code>&gt;&gt;&gt; import urllib
&gt;&gt;&gt; urllib
&lt;module 'urllib' from '/usr/lib/python3.5/urllib/__init__.py'&gt;
&gt;&gt;&gt; urllib.error
&lt;module 'urllib.error' from '/usr/lib/python3.5/urllib/error.py'&gt;
</code></pre>

<p>So perhaps it is something specific to <code>importlib</code>.</p>

<h1>Update #3</h1>

<p>As <strong>@kfb</strong> pointed out in the comments, it does seem to be related to <code>importlib</code> specifically. See the following comment from the <a href="https://hg.python.org/cpython/file/tip/Lib/importlib/__init__.py" rel="nofollow"><code>__init__.py</code> for <code>importlib</code></a>:</p>

<pre><code># 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).
</code></pre>

<p><code>importlib/util.py</code> <em>does</em> import <code>importlib._bootstrap</code> so I would assume that this is realted. If my understanding is correct, when you do <code>import importlib</code> the submodules will be initialized, but are not initialized for the <code>importlib</code> module object that you have imported. At this point, if you do <code>dir(importlib)</code> you will not see <code>util</code>. Interestingly, <em>after</em> you have tried to access <code>importlib.util</code> and gotten an <code>AttributeError</code>, <code>util</code> (along with the other submodules) gets loaded/initialized, and now you <em>can</em> access <code>importlib.util</code>!</p>

<pre><code>&gt;&gt;&gt; import importlib
&gt;&gt;&gt; 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']
&gt;&gt;&gt; importlib.util
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
AttributeError: module 'importlib' has no attribute 'util'
&gt;&gt;&gt; importlib.util
&lt;module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'&gt;
&gt;&gt;&gt; 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']
</code></pre>

python python-3.x python-importlib