Skip to content
Snippets Groups Projects
Commit ea231e25 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

Use Module class

* Methods returning module References now directly return Module
* Methods taking a module Reference now directly take a Module
* Run/runStream/evaluate forward to corresponding Module methods
* AutorunStream is now in Module (where it belongs, since you always
  execute in the context of a module)

Notice that this is backward compatible because  Reference& arguments
where changed to Module (no &) arguments. Hence calling run(...,m)
with a Reference m will create a temporary Module object from r.
This has the advantage that we can centralize all error cheching
in Module while beeing type-safe (in the python sense).
parent ac34c148
Branches
Tags
No related merge requests found
......@@ -15,6 +15,7 @@
#include <dune/common/exceptions.hh>
#include <dune/fufem/python/reference.hh>
#include <dune/fufem/python/module.hh>
namespace Python
......@@ -127,9 +128,9 @@ void stop()
* \param moduleName Name of the module to import
* \returns Python module of given name
*/
Reference import(const std::string& moduleName)
Module import(const std::string& moduleName)
{
Reference pModule = PyImport_ImportModule(moduleName.c_str());
Module pModule = PyImport_ImportModule(moduleName.c_str());
if (not pModule)
DUNE_THROW(Dune::Exception, "failed to retrieve python module " << moduleName);
return pModule;
......@@ -149,10 +150,10 @@ Reference import(const std::string& moduleName)
* \param moduleName Name of the module to import
* \returns Python module of given name
*/
Reference createModule(const std::string& moduleName)
Module createModule(const std::string& moduleName)
{
// PyImport_AddModule returnes a borrowed reference so we have to call inc.
Reference pModule = Imp::inc(PyImport_AddModule(moduleName.c_str()));
Module pModule = Imp::inc(PyImport_AddModule(moduleName.c_str()));
if (not pModule)
DUNE_THROW(Dune::Exception, "failed to create python module " << moduleName);
Reference pBuiltin = Python::import("__builtin__");
......@@ -161,6 +162,18 @@ Reference createModule(const std::string& moduleName)
return pModule;
}
/**
* \brief Obtain the main module
*
* This is a shortcut for import("__main__")
*
* \returns Python main module
*/
Module main()
{
return import("__main__");
}
/**
* \brief Run python code given as string
*
......@@ -198,62 +211,6 @@ void run(const std::string& code, Reference& module)
PyRun_String(code.c_str(), Py_file_input, dict, dict);
}
/**
* \brief A stream that executed all python code it is feeded with on destruction
*
* This class is not inteded to be used directly.
* It is only a helper class for the runStream() function.
*/
class AutoRunCodeStream :
public std::stringstream
{
friend AutoRunCodeStream runStream();
friend AutoRunCodeStream runStream(Reference&);
public:
/**
* \brief Destructor
*
* This will execute the code feeded to the stream
* at once.
*/
~AutoRunCodeStream()
{
if (isModule(module_))
Python::run(this->str(), module_);
else
Python::run(this->str());
}
protected:
/**
* \brief Default constructor
*/
AutoRunCodeStream()
{}
/**
* \brief Default constructor
*/
AutoRunCodeStream(Reference& module) :
module_(module)
{}
/**
* \brief Copy constructor
*
* This will not copy the code feeded to the copied object
* to the newly created one in order to avoid unintended
* multiple execution.
*/
AutoRunCodeStream(const AutoRunCodeStream& other) :
module_(other.module_)
{}
private:
Reference module_;
};
/**
* \brief Obtain a stream to feed the code with multiple lines of python code
*
......@@ -277,9 +234,9 @@ class AutoRunCodeStream :
*
* \returns A stream that will execute all feeded code on destruction
*/
AutoRunCodeStream runStream()
Module::AutoRunCodeStream runStream()
{
return AutoRunCodeStream();
return Module::AutoRunCodeStream();
}
/**
......@@ -293,11 +250,9 @@ AutoRunCodeStream runStream()
* \param module A python object referring to a module
* \returns A stream that will execute all feeded code on destruction
*/
AutoRunCodeStream runStream(Reference& module)
Module::AutoRunCodeStream runStream(Module module)
{
if (not isModule(module))
DUNE_THROW(Dune::Exception, "tried to use non-module where a module is expected");
return AutoRunCodeStream(module);
return module.runStream();
}
/**
......@@ -326,14 +281,9 @@ void runFile(const std::string& fileName)
* \param fileName A string containing the file name
* \param module A python object referring to a module
*/
void runFile(const std::string& fileName, Reference& module)
void runFile(const std::string& fileName, Module module)
{
if (not isModule(module))
DUNE_THROW(Dune::Exception, "tried to use non-module where a module is expected");
Python::Reference dict = module.get("__dict__");
// the last argument specifies that the file should be closed
// after executing the code
PyRun_FileEx(fopen(fileName.c_str(), "r"), fileName.c_str(), Py_file_input, dict, dict, 1);
module.runFile(fileName);
}
/**
......@@ -347,14 +297,13 @@ void runFile(const std::string& fileName, Reference& module)
*/
Reference evaluate(const std::string& expression)
{
Python::Reference dict = Python::import("__main__").get("__dict__");
return PyRun_String(expression.c_str(), Py_eval_input, dict, dict);
Module main = Python::import("__main__");
return main.evaluate(expression);
}
Reference evaluate(const std::string& expression, Reference& module)
Reference evaluate(const std::string& expression, Module module)
{
Python::Reference dict = module.get("__dict__");
return PyRun_String(expression.c_str(), Py_eval_input, dict, dict);
return module.evaluate(expression);
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment