I'm trying to create a plugin framework similar to yapsy (unfortunately yapsy is not python3 compatible).
My code looks like this:
root
main.py
plugins/
__init__.py
PluginManager.py
UI/
__init__.py
textui.py
In PluginManager.py I defined the following class:
class PluginMetaclass(type):
def __init__(cls, name, base, attrs):
if not hasattr(cls, 'registered'):
cls.registered = []
else:
cls.registered.append((name,cls))
class UI_Plugins(object):
__metaclass__ = PluginMetaclass
#...some code here....
def load():
#...some code here too...
if "__init__" in os.path.basename(candidate_filepath):
sys.path.append(plugin_info['path'])
try:
candidateMainFile = open(candidate_filepath+".py","r")
exec(candidateMainFile,candidate_globals)
except Exception as e:
logging.error("Unable to execute the code in plugin: %s" % candidate_filepath)
logging.error("\t The following problem occured: %s %s " % (os.linesep, e))
if "__init__" in os.path.basename(candidate_filepath):
sys.path.remove(plugin_info['path'])
continue
where candidate_filepath contains the plugin path.
textui.py contains the following:
from root.plugins.PluginManager import UI_Plugins
class TextBackend(UI_Plugins):
def run(self):
print("c")
When I try to load the plugin I get this error:
No module named plugins.PluginManager
How can I solve this problem?
The import statement
from root.plugins.PluginManager import UI_Plugins
doesn't work because root
is not a package.
However, if the application is started with
python3 root/main.py
then root
doesn't actually need to be a package.
All you need to do is change the the import statement in textui.py
to
from plugins.PluginManager import UI_Plugins
and everthing should work correctly.
The reason this works, is because the directory of the currently running script is always automatically added to the start of sys.path
. In your case, this will be the root
, and since plugins
is a package within that directory, it can be directly imported from anywhere within your application. So, as long as your main
script remains where it is, there should be no need for any other path manipulations.