daxvena
daxvena

Reputation: 1150

Multiple imports of the same file name

I am trying to create a plugin system and I have a function that imports all the modules into an array.

Layout of Plugins:

pluginsDir/

pluginsDir/chat

pluginsDir/chat/main.py

And this is the function that finds and imports the plugins:

if os.path.exists(pluginsDir):
    for path, dirArray, fileArray in os.walk(pluginsDir):
        for fileName in fileArray:
            if fileName == "main.py":
            sys.path.append(path)
            try:
                plugins.append(__import__("main"))
            except:
                print 'Could not import plugin, "'+path+'": plugin contains errors or is not a real plugin.'

This is fine if I only have one plugin but when I have multiple plugins it keeps importing the first plugin it detects.

Layout of Plugins:

pluginsDir/

pluginsDir/chat

pluginsDir/chat/main.py

pluginsDir/build

pluginsDir/build/main.py

I've tried to addsys.path.remove(path)after my try statement, but it doesn't remove the path after I have already imported the module.

What can I do to import my plugins correctly?

Upvotes: 0

Views: 1851

Answers (3)

Paulo Scardine
Paulo Scardine

Reputation: 77281

The Python module system is just a very cool way to handle namespaces. Importing several modules with the same name to your current namespace will clutter it.

No need to traverse the pluginsDir and import each file, Python will do that for you (from pluginsDir import *). If main.py does only initialization stuf you can move the code to pluginsDir/chat/__init__.py.

Import pluginsDir refering to your plugins like 'pluginsDir.chat' is considered better pratice.

Upvotes: 2

brildum
brildum

Reputation: 1799

sys.path.append(path) will attach the plugin folder to the end of sys.path. Since Python searches folders in sys.path from front to back, appending additional paths to the end of the list will not be found because any main.py modules in folder specified earlier in sys.path will essentially hide modules in folders at the end of the list. Instead, you could use sys.path.insert(0, path) to add new paths to the front of the list.

You should look at Python packages for a way to better structure the plugins.

plugindir/
    __init__.py
    plugin1/
        __init__.py
    plugin2/
        __init__.py

With Python packages, the loop in your script can be easily implemented with:

sys.path.insert(0, path_to_plugindir)
for folder in dirArray:
    __import__(folder)

Upvotes: 4

Emilio M Bumachar
Emilio M Bumachar

Reputation: 2613

Your inner for loop is not indented, I don't see why your code runs at all. Fixing the indentation might fix the problem.

Upvotes: 0

Related Questions