30

Some of my code use the now deprecated imp package to find a module

toolboxFile, toolboxPath, toolboxDescription = imp.find_module("Tools")

What is the equivalent function or code to get the same results with package importlib ?

Marc
  • 666
  • 1
  • 6
  • 18

3 Answers3

12

Same folder

If the module is in your working directory, importlib.util.find_spec probably suffices for your purposes.

For example if you just want to load the module, you can use:

  • deprecated in Python 3.5 and higher:

    toolbox_specs = importlib.util.find_spec("Tools")
    toolbox = toolbox_specs.loader.load_module()
    
  • introduced in Python 3.5 and higher:

    toolbox_specs = importlib.util.find_spec("Tools")
    toolbox = importlib.util.module_from_spec(toolbox_specs)
    toolbox_specs.loader.exec_module(toolbox)
    

    Caveat: I haven’t tested this, but it’s straight from the documentation, so I suppose it works.

You can assess several other properties with the toolbox_specs object. However, e.g., a corresponding file object is not amongst them. If you really need this in Python 3, you probably have to obtain the file’s path and open it with other methods.

Different folder

To find a module in a different folder, you have to work with a FileFinder, which in turn needs to know the module’s type. For example, if your module is an extension, you can find the specs as follows:

loader_details = (
    importlib.machinery.ExtensionFileLoader,
    importlib.machinery.EXTENSION_SUFFIXES
    )

toolsfinder = importlib.machinery.FileFinder("Folder_of_Tools", loader_details)
toolbox_specs = toolsfinder.find_spec("Tools")

You can then process toolbox_specs as described above.

Wrzlprmft
  • 3,470
  • 1
  • 27
  • 44
  • If `Tools` does an implicit sibling import (e.g. `import foo` and there is a `foo.py` file along side `Tools.py`), this solution yields `ModuleNotFoundError: No module named 'foo'`. Any way to address this? – Pedro Cattori Jan 24 '17 at 18:42
  • @PedroCattori: I am not entirely sure what your situation is, let allone how to address it. I suggest you ask a separate question on this. – Wrzlprmft Jan 25 '17 at 19:11
9

I found this worked as a replacement for imp.find_module()

importlib.machinery.PathFinder().find_spec(modName, modDirList)
Marcel Wilson
  • 2,803
  • 20
  • 43
  • 1
    What is provided as modDirList? – user48956 Jun 19 '20 at 01:35
  • "module Directory List" if I remember the naming convention on that example. It was a list of strings where each string was a particular directory containing the modules we are trying to find. Basically it's the path. – Marcel Wilson Jun 22 '20 at 19:34
-1

According to Python official documentation in this page imp

find_module Deprecated since version 3.3 Use importlib.util.find_spec() instead unless Python 3.3 compatibility is required, in which case use importlib.find_loader().

Use importlib.util.find_spec("Tools") for find spec for more information you can see this link.

And use importlib.find_loader("Tools") for find loader more information

EDIT:

sample code

import importlib
import importlib.util
import sys

    name="test"
    moduledir="d:\\dirtest"
# this is optional set that if you what load from specific directory
    try:
        spec = importlib.util.find_spec(name,moduledir)
        if spec is None:
            print("Import error 0: " + " module not found")
            sys.exit(0)
        toolbox = spec.loader.load_module()
    except (ValueError, ImportError) as msg:
        print("Import error 3: "+str(msg))
        sys.exit(0)

    print("load module")
Mehdi
  • 1,725
  • 1
  • 15
  • 33
  • Can you address whether and how any of these commands allows you to find modules in a different path than the working path? – Wrzlprmft May 16 '16 at 18:54
  • 1
    Your example code does not work for me if `moduledir` is not the current directory (also the indentation is broken), even if there is a module in that directory that would be found otherwise. Does it work for you? If yes, we may have found a bug. If no, we either have a bug or misunderstood how it works. – Wrzlprmft May 17 '16 at 06:22
  • Yes it works for me version test with python version 3.4.4 – Mehdi May 17 '16 at 07:29
  • As it stands, this code does not work and is not intended to do so. [`find_spec`](http://docs.python.org/3/library/importlib.html#importlib.util.find_spec) does not take a directory as second argument. The variant with `find_loader` should not have worked either, as this takes a list of directiories and not a directory as an argument. – Wrzlprmft May 27 '16 at 08:51