title: Importing module with "current-directory" imports
body: <p>I have the following code to load a module dynamically:</p>
  
  <pre><code>def load_module(absolute_path):
      import importlib.util
      module_name, _ = os.path.splitext(os.path.split(absolute_path)[-1])
      try:
          py_mod = imp.load_source(module_name, absolute_path)
      except ImportError:
          module_root = os.path.dirname(absolute_path)
          print("Could not directly load module, including dir: {}".format(module_root))
          spec = importlib.util.spec_from_file_location(
              module_name, absolute_path, submodule_search_locations=[module_root, "."])
          py_mod = importlib.util.module_from_spec(spec)
          spec.loader.exec_module(py_mod)
      return py_mod
  </code></pre>
  
  <p>It works really well, except for the case when it is trying to import a script in the same folder (and not part of a package with the same name). For example, script <code>a.py</code> is doing <code>import b</code>. It results in the error <code>ImportError: No module named 'b'</code> (which is common for Python 3).</p>
  
  <p>But I would really like to find a way to solve this? It would be solved by prepending:</p>
  
  <pre><code>import sys
  sys.path.append(".")
  </code></pre>
  
  <p>to script "a".</p>
  
  <p>Though I hoped it could have been solved by: </p>
  
  <pre><code>submodule_search_locations=[module_root, "."]
  </code></pre>
  
  <p>Oh yea, the rationale is that I also want to support importing modules that are not proper packages/modules, but just some scripts that would work in an interpreter.</p>
  
  <p><strong>Reproducible code</strong>:</p>
  
  <h2>~/example/a.py</h2>
  
  <pre><code>import b
  </code></pre>
  
  <h2>~/example/b.py</h2>
  
  <pre><code>print("hi")
  </code></pre>
  
  <h2>~/somewhere_else/main.py (located different from a/b)</h2>
  
  <pre><code>import sys, os, imp, importlib.util
  
  def load_module(absolute_path) ...
  
  load_module(sys.argv[1])
  </code></pre>
  
  <p>Then run on command line:</p>
  
  <pre><code>cd ~/somewhere_else
  python3.5 main.py /home/me/example/a.py
  </code></pre>
  
  <p>which results in <code>ImportError: No module named 'b'</code></p>
  
  <p>The following code solves it, but of course we cannot put <code>sys.path</code> stuff manually in all scripts.</p>
  
  <h2>~/example/a.py (2)</h2>
  
  <pre><code>import sys
  sys.path.append(".")
  import b
  </code></pre>
  
  <p>I really hope others might have a solution that I didn't think of yet.</p>
  
  <h1>Appendix</h1>
  
  <pre><code>def load_module(absolute_path):
      import importlib.util
      module_name, _ = os.path.splitext(os.path.split(absolute_path)[-1])
      try:
          py_mod = imp.load_source(module_name, absolute_path)
      except ImportError as e:
          if "No module named" not in e.msg:
              raise e
  
          missing_module = e.name
          module_root = os.path.dirname(absolute_path)
  
          if missing_module + ".py" not in os.listdir(module_root):
              msg = "Could not find '{}' in '{}'"
              raise ImportError(msg.format(missing_module, module_root))
  
          print("Could not directly load module, including dir: {}".format(module_root))
          sys.path.append(module_root)
          spec = importlib.util.spec_from_file_location(module_name, absolute_path)
          py_mod = importlib.util.module_from_spec(spec)
          spec.loader.exec_module(py_mod)
      return py_mod
  </code></pre>