Skip to content

Commit cb07dac

Browse files
committed
[SofaPython3] Restore the plugins automatic registering of path to python libraries.
When we load a c++ plugin it may be packaged with additional python files (examples, libraries, or per plugin binding). These files should be visible from the python environment. This is done by the added code that scans the plugin's directory and register any path matching the following patterns: pluginName/lib/site-packages pluginName/lib/python3/site-packages This behavior was the implemented in the previous version of SofaPython and proved to be useful.
1 parent 0a941c5 commit cb07dac

File tree

2 files changed

+63
-16
lines changed

2 files changed

+63
-16
lines changed

Plugin/src/SofaPython3/PythonEnvironment.cpp

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,34 +52,37 @@ along with sofaqtquick. If not, see <http://www.gnu.org/licenses/>.
5252
#include <dlfcn.h>
5353
#endif
5454

55+
#include <sofa/helper/system/PluginManager.h>
56+
using sofa::helper::system::PluginManager;
57+
using sofa::helper::system::Plugin;
58+
5559
#include <sofa/helper/system/FileRepository.h>
56-
#include <sofa/helper/system/FileSystem.h>
5760
#include <sofa/helper/system/SetDirectory.h>
61+
#include <sofa/helper/system/FileSystem.h>
62+
using sofa::helper::system::FileSystem;
5863

5964
#include <sofa/helper/Utils.h>
65+
using sofa::helper::Utils;
66+
6067
#include <sofa/helper/StringUtils.h>
6168
using sofa::helper::getAStringCopy ;
6269

63-
using sofa::helper::system::FileSystem;
64-
using sofa::helper::Utils;
65-
6670
#include <SofaPython3/PythonEnvironment.h>
6771

6872
#include <sofa/helper/logging/Messaging.h>
69-
MSG_REGISTER_CLASS(sofapython3::PythonEnvironment, "SofaPython3::PythonEnvironment")
7073

7174
#include <sofa/simulation/SceneLoaderFactory.h>
7275
using sofa::simulation::SceneLoaderFactory;
7376

74-
//#include "Python.h"
75-
7677
#include <pybind11/embed.h>
7778
#include <pybind11/eval.h>
7879
namespace py = pybind11;
7980

8081
#include "SceneLoaderPY3.h"
8182
using sofapython3::SceneLoaderPY3;
8283

84+
MSG_REGISTER_CLASS(sofapython3::PythonEnvironment, "SofaPython3::PythonEnvironment")
85+
8386
namespace sofapython3
8487
{
8588

@@ -248,6 +251,8 @@ void PythonEnvironment::Init()
248251
}
249252
}
250253

254+
addPythonModulePathsForPluginsByName("SofaPython3");
255+
251256
getStaticData()->m_sofamodule = py::module::import("Sofa");
252257

253258

@@ -318,23 +323,64 @@ void PythonEnvironment::addPythonModulePathsFromConfigFile(const std::string& pa
318323

319324
void PythonEnvironment::addPythonModulePathsForPlugins(const std::string& pluginsDirectory)
320325
{
326+
bool added = false;
327+
328+
std::vector<std::string> pythonDirs = {
329+
pluginsDirectory,
330+
pluginsDirectory + "/lib",
331+
pluginsDirectory + "/python3"
332+
};
333+
334+
/// Iterate in the pluginsDirectory and add each sub directory with a 'python' name
335+
/// this is mostly for in-tree builds.
321336
std::vector<std::string> files;
322337
FileSystem::listDirectory(pluginsDirectory, files);
323-
324338
for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i)
325339
{
326-
const std::string pluginPath = pluginsDirectory + "/" + *i;
327-
if (FileSystem::exists(pluginPath) && FileSystem::isDirectory(pluginPath))
340+
const std::string pluginSubdir = pluginsDirectory + "/" + *i;
341+
if (FileSystem::exists(pluginSubdir) && FileSystem::isDirectory(pluginSubdir))
328342
{
329-
const std::string pythonDir = pluginPath + "/python";
330-
if (FileSystem::exists(pythonDir) && FileSystem::isDirectory(pythonDir))
331-
{
332-
addPythonModulePath(pythonDir);
333-
}
343+
pythonDirs.push_back(pluginSubdir + "/python3");
334344
}
335345
}
346+
347+
/// For each of the directories in pythonDirs, search for a site-packages entry
348+
for(std::string pythonDir : pythonDirs)
349+
{
350+
// Search for a subdir "site-packages"
351+
if (FileSystem::exists(pythonDir+"/site-packages") && FileSystem::isDirectory(pythonDir+"/site-packages"))
352+
{
353+
addPythonModulePath(pythonDir+"/site-packages");
354+
added = true;
355+
}
356+
}
357+
358+
if(!added)
359+
{
360+
msg_warning("PythonEnvironment") << "No python dir found in " << pluginsDirectory;
361+
}
336362
}
337363

364+
void PythonEnvironment::addPythonModulePathsForPluginsByName(const std::string& pluginName)
365+
{
366+
std::map<std::string, Plugin>& map = PluginManager::getInstance().getPluginMap();
367+
for( const auto& elem : map)
368+
{
369+
Plugin p = elem.second;
370+
if ( p.getModuleName() == pluginName )
371+
{
372+
std::string pluginLibraryPath = elem.first;
373+
// moduleRoot should be 2 levels above the library (plugin_name/lib/plugin_name.so)
374+
std::string moduleRoot = FileSystem::getParentDirectory(FileSystem::getParentDirectory(pluginLibraryPath));
375+
376+
addPythonModulePathsForPlugins(moduleRoot);
377+
return;
378+
}
379+
}
380+
msg_warning("PythonEnvironment") << pluginName << " not found in PluginManager's map.";
381+
}
382+
383+
338384
// some basic RAII stuff to handle init/termination cleanly
339385
namespace
340386
{

Plugin/src/SofaPython3/PythonEnvironment.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ class SOFAPYTHON3_API PythonEnvironment
9494

9595
/// Add all the directories matching <pluginsDirectory>/*/python to sys.path
9696
/// NB: can also be used for projects <projectDirectory>/*/python
97-
static void addPythonModulePathsForPlugins(const std::string& pluginsDirectory);
97+
static void addPythonModulePathsForPlugins(const std::string& pluginsDirectory);
98+
static void addPythonModulePathsForPluginsByName(const std::string& pluginName);
9899

99100
/// set the content of sys.argv.
100101
static void setArguments(const std::string& filename,

0 commit comments

Comments
 (0)