Skip to content

Commit a421385

Browse files
committed
Properly load plugins.
1 parent 260c9dc commit a421385

File tree

4 files changed

+30
-29
lines changed

4 files changed

+30
-29
lines changed

src/proxy/proxypython.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,18 @@ QList<QList<QObject*>> ProxyPython::load(const PluginExtension& extension)
120120
return {};
121121
}
122122

123-
// currently, only handle __init__.py directly in the folder
124-
const auto pyIniFile = extension.directory() / "__init__.py";
125-
if (!exists(pyIniFile)) {
123+
if (extension.autodetect()) {
124+
log::error("{}: automatic plugin detection is not supported for Python plugins",
125+
extension.metadata().name());
126126
return {};
127127
}
128128

129-
m_ExtensionModules[&extension] = {pyIniFile};
129+
m_ExtensionModules[&extension] = {};
130130

131131
QList<QList<QObject*>> plugins;
132-
for (auto&& pythonModule : m_ExtensionModules[&extension]) {
133-
plugins.append(m_Runner->load(pythonModule));
132+
for (auto& [moduleName, modulePath] : extension.plugins()) {
133+
m_ExtensionModules[&extension].push_back({moduleName, modulePath});
134+
plugins.append(m_Runner->load(moduleName, modulePath));
134135
}
135136

136137
return plugins;
@@ -143,8 +144,8 @@ void ProxyPython::unload(const PluginExtension& extension)
143144
}
144145

145146
if (auto it = m_ExtensionModules.find(&extension); it != m_ExtensionModules.end()) {
146-
for (auto&& pythonModule : it->second) {
147-
m_Runner->unload(pythonModule);
147+
for (auto& [moduleName, modulePath] : it->second) {
148+
m_Runner->unload(moduleName, modulePath);
148149
}
149150
m_ExtensionModules.erase(it);
150151
}
@@ -154,8 +155,8 @@ void ProxyPython::unloadAll()
154155
{
155156
if (m_Runner) {
156157
for (auto& [ext, modules] : m_ExtensionModules) {
157-
for (auto& pythonModule : modules) {
158-
m_Runner->unload(pythonModule);
158+
for (auto& [moduleName, modulePath] : modules) {
159+
m_Runner->unload(moduleName, modulePath);
159160
}
160161
}
161162
}

src/proxy/proxypython.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class ProxyPython : public MOBase::IPluginLoader {
5757
HMODULE m_RunnerLib;
5858
std::unique_ptr<mo2::python::IPythonRunner> m_Runner;
5959
std::unordered_map<const MOBase::PluginExtension*,
60-
std::vector<std::filesystem::path>>
60+
std::vector<std::pair<std::string, std::filesystem::path>>>
6161
m_ExtensionModules;
6262
};
6363

src/runner/pythonrunner.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ namespace mo2::python {
3636
PythonRunner() = default;
3737
~PythonRunner() = default;
3838

39-
QList<QList<QObject*>> load(std::filesystem::path const& pythonModule) override;
40-
void unload(std::filesystem::path const& pythonModule) override;
39+
QList<QList<QObject*>> load(std::string_view moduleName,
40+
std::filesystem::path const& modulePath) override;
41+
void unload(std::string_view moduleName,
42+
std::filesystem::path const& modulePath) override;
4143

4244
bool initialize(std::vector<std::filesystem::path> const& pythonPaths) override;
4345
void addDllSearchPath(std::filesystem::path const& dllPath) override;
@@ -150,7 +152,8 @@ namespace mo2::python {
150152
py::module_::import("os").attr("add_dll_directory")(absolute(dllPath));
151153
}
152154

153-
QList<QList<QObject*>> PythonRunner::load(const std::filesystem::path& pythonModule)
155+
QList<QList<QObject*>> PythonRunner::load(std::string_view name,
156+
const std::filesystem::path& pythonModule)
154157
{
155158
py::gil_scoped_acquire lock;
156159

@@ -160,24 +163,19 @@ namespace mo2::python {
160163
auto sys = py::module_::import("sys");
161164
auto importlib_util = py::module_::import("importlib.util");
162165

163-
// check the file type
164-
const auto moduleName =
165-
pythonModule.filename() == "__init__.py"
166-
? pythonModule.parent_path().filename().u8string()
167-
: pythonModule.filename().u8string();
168-
169166
// check if the module is already loaded
170167
py::dict modules = sys.attr("modules");
171168
py::module_ pymodule;
172-
if (modules.contains(moduleName)) {
173-
pymodule = modules[py::str(moduleName)];
169+
if (modules.contains(name)) {
170+
pymodule = modules[py::str(name)];
174171
pymodule.reload();
175172
}
176173
else {
177174
// load the module
178-
auto spec = importlib_util.attr("find_spec")(moduleName, pythonModule);
179-
pymodule = importlib_util.attr("module_from_spec")(spec);
180-
sys.attr("modules")[py::str(moduleName)] = pymodule;
175+
auto spec =
176+
importlib_util.attr("spec_from_file_location")(name, pythonModule);
177+
pymodule = importlib_util.attr("module_from_spec")(spec);
178+
sys.attr("modules")[py::str(name)] = pymodule;
181179
spec.attr("loader").attr("exec_module")(pymodule);
182180
}
183181

@@ -243,12 +241,13 @@ namespace mo2::python {
243241
}
244242
}
245243

246-
void PythonRunner::unload(const std::filesystem::path& pythonModule)
244+
void PythonRunner::unload(std::string_view moduleName,
245+
std::filesystem::path const& modulePath)
247246
{
248247
py::gil_scoped_acquire lock;
249248

250249
// At this point, the identifier is the full path to the module.
251-
QDir folder(pythonModule);
250+
QDir folder(modulePath);
252251

253252
// we want to "unload" (remove from sys.modules) modules that come
254253
// from this plugin (whose __path__ points under this module,

src/runner/pythonrunner.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ namespace mo2::python {
2424
class IPythonRunner {
2525
public:
2626
virtual QList<QList<QObject*>>
27-
load(std::filesystem::path const& pythonModule) = 0;
28-
virtual void unload(std::filesystem::path const& pythonModule) = 0;
27+
load(std::string_view moduleName, std::filesystem::path const& modulePath) = 0;
28+
virtual void unload(std::string_view moduleName,
29+
std::filesystem::path const& modulePath) = 0;
2930

3031
// initialize Python
3132
//

0 commit comments

Comments
 (0)