Skip to content
Snippets Groups Projects
Commit a4cd409e authored by Pospelov, Gennady's avatar Pospelov, Gennady
Browse files

Method in PyImport namespace to retrieve list of function in a module.

parent 8fb8f96d
No related branches found
No related tags found
No related merge requests found
......@@ -58,3 +58,39 @@ std::unique_ptr<MultiLayer> PyImport::createFromPython(const std::string& script
return result;
}
std::vector<std::string> PyImport::listOfFunctions(const std::string& script,
const std::string& path)
{
PyEmbeddedUtils::import_bornagain(path);
PyObject* pCompiledFn = Py_CompileString( script.c_str() , "" , Py_file_input ) ;
if (!pCompiledFn)
throw std::runtime_error("Can't compile a function");
// create a module
PyObject* pModule = PyImport_ExecCodeModule((char *)"test" , pCompiledFn ) ;
if (!pModule)
throw std::runtime_error("Can't exec module");
PyObject *dict = PyModule_GetDict(pModule);
if (!dict)
throw std::runtime_error("Can't get dictionary from module");
std::vector<std::string> result;
PyObject *key, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(dict, &pos, &key, &value)) {
if(PyCallable_Check(value)) {
std::string func_name = PyEmbeddedUtils::toString(key);
if (func_name.find("__") == std::string::npos)
result.push_back(func_name);
}
}
Py_DecRef( dict ) ;
Py_DecRef( pModule ) ;
Py_DecRef( pCompiledFn ) ;
return result;
}
......@@ -18,6 +18,7 @@
#include "WinDllMacros.h"
#include <string>
#include <vector>
#include <memory>
class MultiLayer;
......@@ -26,10 +27,17 @@ namespace PyImport {
//! Creates a multi layer by running python code in embedded interpreter.
//! @param script: Python script
//! @param functionName: A function name in this script which produces a MultiLayer.
//! @param functionName: A function name in this script which produces a MultiLayer
//! @param path: A path to import BornAgain library. If empty, relies on PYTHONPATH
BA_CORE_API_ std::unique_ptr<MultiLayer> createFromPython(const std::string& script,
const std::string& functionName,
const std::string& path = std::string());
//! Returns list of functions defined in the script.
//! @param script: Python script
//! @param path: A path to import BornAgain library. If empty, relies on PYTHONPATH
BA_CORE_API_ std::vector<std::string> listOfFunctions(const std::string& script,
const std::string& path = std::string());
}
#endif
......
......@@ -8,6 +8,7 @@ set(test_cases
CompiledFunction
ObjectExtract
ExportToPythonAndBack
ModuleFunctionsList
)
# for some reason these flags doesn't propagated here by SetUpWindows.cmake
......
......@@ -42,5 +42,8 @@ PyEmbeddedTestFactory::PyEmbeddedTestFactory()
registerItem("ExportToPythonAndBack",
create_new<ExportToPythonAndBack>,
"Export of standard multilayer to Python code and casting back.");
registerItem("ModuleFunctionsList",
create_new<ModuleFunctionsList>,
"Explores the content of imported module for the list of defined functions.");
}
......@@ -395,3 +395,25 @@ bool ExportToPythonAndBack::runTest()
return code == new_code;
}
//! Retrieves list of functions from the imported script and checks, that there is
//! one function in a dictioonary with name "get_simulation".
bool ModuleFunctionsList::runTest()
{
// compile our function
std::stringstream buf ;
buf << "import bornagain as ba \n";
buf << " \n";
buf << "def get_simulation(): \n";
buf << " m_ambience = ba.HomogeneousMaterial(\"Air\", 0.0, 0.0) \n";
buf << " air_layer = ba.Layer(m_ambience) \n";
buf << " multilayer = ba.MultiLayer() \n";
buf << " multilayer.addLayer(air_layer) \n";
buf << " return multilayer \n";
auto listOfFunc = PyImport::listOfFunctions(buf.str(), BABuild::buildLibDir());
for(auto s: listOfFunc)
std::cout << "AAA" << s << std::endl;
return listOfFunc.size() == 1 && listOfFunc.at(0) == "get_simulation";
}
......@@ -82,4 +82,12 @@ protected:
bool runTest();
};
//! Explores the content of imported module for the list of defined functions.
class ModuleFunctionsList : public IFunctionalTest
{
protected:
bool runTest();
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment