Skip to content

Commit 277aa50

Browse files
committed
[SofaPython3] Separates the pre-loaded python modules out of the python environment (BUGFIX)
The execution of Sofa from a python3 environement is not working anymore because some features need Sofa & SofaRuntime modules to be loaded but the loading is done when initializing only in the embeded python interpreter. To fix this, the PR move the module loading and access into its own singleton that initialize at first use. Fixing that is important for 22.06 release. For the future, refactoring the PythonEnvironment file to split PythonEnvironment in two, to separate what is actually relevant for the PythonEnvironment and what should be part something like PythonEmbededInterpreter.
1 parent cb97cab commit 277aa50

2 files changed

Lines changed: 30 additions & 10 deletions

File tree

Plugin/src/SofaPython3/PythonEnvironment.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ MSG_REGISTER_CLASS(sofapython3::PythonEnvironment, "SofaPython3::PythonEnvironme
6060
namespace sofapython3
6161
{
6262

63+
class PythonEnvironmentModule
64+
{
65+
public:
66+
py::module m_sofaModule ;
67+
py::module m_sofaRuntimeModule ;
68+
};
69+
6370
////////////////////////////////////////////////////////////////////////////////////////////////////
6471
/// \brief The PythonEnvironmentData class which hold "static" data as long as python is running
6572
///
@@ -102,9 +109,6 @@ class PythonEnvironmentData
102109
}
103110

104111
std::set<std::string> addedPath;
105-
106-
py::module m_sofaModule ;
107-
py::module m_sofaRuntimeModule ;
108112
private:
109113
std::vector<wchar_t*> m_argv;
110114
};
@@ -114,11 +118,28 @@ PythonEnvironmentData* PythonEnvironment::getStaticData()
114118
static PythonEnvironmentData* m_staticdata { nullptr } ;
115119

116120
if( !m_staticdata )
121+
{
117122
m_staticdata = new PythonEnvironmentData();
118-
123+
}
119124
return m_staticdata;
120125
}
121126

127+
PythonEnvironmentModule* PythonEnvironment::getStaticModule()
128+
{
129+
PythonEnvironment::gil lock;
130+
131+
static PythonEnvironmentModule* m_staticmodule { nullptr } ;
132+
if( !m_staticmodule )
133+
{
134+
m_staticmodule = new PythonEnvironmentModule();
135+
executePython([]{
136+
getStaticModule()->m_sofaModule = py::module::import("Sofa");
137+
getStaticModule()->m_sofaRuntimeModule = py::module::import("SofaRuntime");
138+
});
139+
}
140+
return m_staticmodule;
141+
}
142+
122143
std::string PythonEnvironment::pluginLibraryPath = "";
123144

124145
SOFAPYTHON3_API py::module PythonEnvironment::importFromFile(const std::string& module, const std::string& path, py::object* globals)
@@ -156,7 +177,6 @@ void PythonEnvironment::Init()
156177
SceneLoaderFactory::getInstance()->addEntry(new SceneLoaderPY3());
157178
}
158179

159-
160180
#if defined(__linux__)
161181
// WARNING: workaround to be able to import python libraries on linux (like
162182
// numpy), at least on Ubuntu (see http://bugs.python.org/issue4434). It is
@@ -237,8 +257,6 @@ void PythonEnvironment::Init()
237257
// Lastly, we (try to) add modules from the root of SOFA
238258
addPythonModulePathsFromDirectory( Utils::getSofaPathPrefix() );
239259

240-
executePython([]{ getStaticData()->m_sofaModule = py::module::import("Sofa"); });
241-
executePython([]{ getStaticData()->m_sofaRuntimeModule = py::module::import("SofaRuntime"); });
242260
executePython([]{ PyRun_SimpleString("import SofaRuntime");});
243261

244262
// python livecoding related
@@ -365,7 +383,7 @@ void PythonEnvironment::addPythonModulePathsFromDirectory(const std::string& dir
365383
}
366384

367385
// For each of the directories in pythonDirs, search for a site-packages entry
368-
for(std::string searchDir : searchDirs)
386+
for(std::string& searchDir : searchDirs)
369387
{
370388
// Search for a subdir "site-packages"
371389
if (FileSystem::exists(searchDir + "/site-packages") && FileSystem::isDirectory(searchDir + "/site-packages"))
@@ -508,13 +526,13 @@ std::string PythonEnvironment::getStackAsString()
508526
std::string PythonEnvironment::getPythonCallingPointString()
509527
{
510528
gil lock;
511-
return py::cast<std::string>(getStaticData()->m_sofaModule.attr("getPythonCallingPointAsString")());
529+
return py::cast<std::string>(getStaticModule()->m_sofaModule.attr("getPythonCallingPointAsString")());
512530
}
513531

514532
sofa::helper::logging::FileInfo::SPtr PythonEnvironment::getPythonCallingPointAsFileInfo()
515533
{
516534
gil lock;
517-
py::tuple cp = getStaticData()->m_sofaRuntimeModule.attr("getPythonCallingPoint")();
535+
py::tuple cp = getStaticModule()->m_sofaRuntimeModule.attr("getPythonCallingPoint")();
518536
return SOFA_FILE_INFO_COPIED_FROM(py::cast<std::string>(cp[0]), py::cast<int>(cp[1]));
519537
}
520538

Plugin/src/SofaPython3/PythonEnvironment.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ using sofa::simulation::SceneLoader ;
5252

5353
/// Forward definition
5454
class PythonEnvironmentData ;
55+
class PythonEnvironmentModule ;
5556

5657
class SOFAPYTHON3_API PythonEnvironment
5758
{
@@ -154,6 +155,7 @@ class SOFAPYTHON3_API PythonEnvironment
154155

155156
private:
156157
static PythonEnvironmentData* getStaticData() ;
158+
static PythonEnvironmentModule* getStaticModule() ;
157159
static std::string pluginLibraryPath;
158160
static inline bool s_isInitialized{false};
159161
};

0 commit comments

Comments
 (0)