Commit 54631aac authored by David Gobbi's avatar David Gobbi Committed by Ben Boeckel

Have vtkPythonUtil keep track of loaded modules.

This way, if one module depends on another, then it can check if
that module has already been imported before calling ImportModule.
In this way, people can avoid the ImportModule call completely
by calling "import" themselves inside their Python code, which
allows them to import the modules from a specific location.
parent e0287f1a
......@@ -157,6 +157,12 @@ class vtkPythonEnumMap
{
};
// Keep track of all the VTK-Python extension modules
class vtkPythonModuleList
: public std::vector<std::string>
{
};
// Keep track of all vtkPythonCommand instances.
class vtkPythonCommandList
: public std::vector<vtkWeakPointer<vtkPythonCommand> >
......@@ -211,6 +217,7 @@ vtkPythonUtil::vtkPythonUtil()
this->SpecialTypeMap = new vtkPythonSpecialTypeMap;
this->NamespaceMap = new vtkPythonNamespaceMap;
this->EnumMap = new vtkPythonEnumMap;
this->ModuleList = new vtkPythonModuleList;
this->PythonCommandList = new vtkPythonCommandList;
}
......@@ -223,6 +230,7 @@ vtkPythonUtil::~vtkPythonUtil()
delete this->SpecialTypeMap;
delete this->NamespaceMap;
delete this->EnumMap;
delete this->ModuleList;
delete this->PythonCommandList;
}
......@@ -927,6 +935,16 @@ PyTypeObject *vtkPythonUtil::FindSpecialTypeObject(const char *name)
//--------------------------------------------------------------------
bool vtkPythonUtil::ImportModule(const char *name, PyObject *globals)
{
// check whether the module is already loaded
if (vtkPythonMap)
{
vtkPythonModuleList *ml = vtkPythonMap->ModuleList;
if (std::find(ml->begin(), ml->end(), name) != ml->end())
{
return true;
}
}
// try relative import (const-cast is needed for Python 2.x only)
PyObject *m = PyImport_ImportModuleLevel(const_cast<char *>(name), globals,
nullptr, nullptr, 1);
......@@ -948,6 +966,14 @@ bool vtkPythonUtil::ImportModule(const char *name, PyObject *globals)
return true;
}
//--------------------------------------------------------------------
void vtkPythonUtil::AddModule(const char *name)
{
vtkPythonUtilCreateIfNeeded();
vtkPythonMap->ModuleList->push_back(name);
}
//--------------------------------------------------------------------
// mangle a void pointer into a SWIG-style string
char *vtkPythonUtil::ManglePointer(const void *ptr, const char *type)
......
......@@ -40,6 +40,7 @@ class vtkPythonObjectMap;
class vtkPythonSpecialTypeMap;
class vtkPythonNamespaceMap;
class vtkPythonEnumMap;
class vtkPythonModuleList;
class vtkStdString;
class vtkUnicodeString;
class vtkVariant;
......@@ -200,6 +201,14 @@ public:
*/
static bool ImportModule(const char *name, PyObject *globals);
/**
* Modules call this to add themselves to the list of loaded modules.
* This is needed because we do not know how the modules are arranged
* within their package, so searching sys.modules is unreliable. It is
* best for us to keep our own list.
*/
static void AddModule(const char *name);
/**
* Utility function to build a docstring by concatenating a series
* of strings until a null string is found.
......@@ -244,6 +253,7 @@ private:
vtkPythonSpecialTypeMap *SpecialTypeMap;
vtkPythonNamespaceMap *NamespaceMap;
vtkPythonEnumMap *EnumMap;
vtkPythonModuleList *ModuleList;
vtkPythonCommandList *PythonCommandList;
friend void vtkPythonUtilDelete();
......
......@@ -125,11 +125,12 @@ static void CreateImplFile(const char *libName,
for (i = 0; i < numFiles; i++)
{
fprintf(fout," PyVTKAddFile_%s(d);\n",
files[i]);
fprintf(fout," PyVTKAddFile_%s(d);\n", files[i]);
}
fprintf(fout,"\n");
fprintf(fout," vtkPythonUtil::AddModule(\"%s\");\n\n", libName);
fprintf(fout," return m;\n");
fprintf(fout,"}\n\n");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment