1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#ifndef BALL_PYTHON_PYINTERPRETER_H
#define BALL_PYTHON_PYINTERPRETER_H
// This has to be included before Python.h to prevent macro redefinition clashes in macOS Python...
#include <BALL/SYSTEM/path.h>
#include <BALL/PYTHON/pyKernel.h>
#include <BALL/PYTHON/pyServer.h>
#include <memory>
#include <vector>
#include <QtCore/QList>
#include <QtCore/QPair>
#include <QtCore/QString>
namespace BALL
{
/** Embedded Python interpreter.
There's just one global instance of the interpreter,
so all methods are static. The use of subinterpreters
is not yet supported.
\ingroup PythonExtensions
*/
class BALL_EXPORT PyInterpreter final
{
private:
// We don't want anybody to instantiate this!
PyInterpreter() = default;
~PyInterpreter() = default;
public:
/** @name Type definitions */
//@{
/// Used to encode the individual paths appended to sys.path for dynamic loading of modules.
using PathStrings = std::vector<String>;
//@}
/** @name Initialization */
//@{
/** Initialize the interpreter.
Initialize the interpreter (by calling <tt>Py_Initialize</tt>) and
load the modules <tt>sys</tt>, <tt>site</tt>, and <tt>BALL</tt>.
A second call to <tt>initialize</tt> may be used to restart the intepreter.
Upon start, the paths defined by \link setSysPath \endlink are added to sys.path.
If your interpreter cannot load specific modules, add the location of your
modules here.
*/
static void initialize();
/** Stop the interpreter.
Deallocate all memory occupied by the interpreter
(by calling <tt>Py_Finalize</tt>).
*/
static void finalize();
/** Determine the interpreter state.
@return true if the interpreter is correctly initialized
*/
static bool isInitialized() { return kernel_ && kernel_->isStarted(); }
/**
* Append additional search paths to sys.path upon initialization
* @deprecated Old String API; Might be re-added under a less misleading name in the future
*/
BALL_DEPRECATED static void setSysPath(const PathStrings& path_strings) { sys_path_ = path_strings; }
/**
* Get the current (additional) paths added to sys.path
* @deprecated Old String API; Might be re-added under a less misleading name in the future
*/
BALL_DEPRECATED static const PathStrings& getSysPath() { return sys_path_; }
/// @deprecated Returns PyInterpreter::isInitialized()
BALL_DEPRECATED static bool isValid() { return isInitialized(); }
/// @deprecated Error messages are directly printed to Log.error; Always returns an empty string.
BALL_DEPRECATED static String getStartupLog() { return String(); }
//@}
/** @name Execution */
//@{
/** Execute a string.
@param s the string to run (may contain multiple lines with correct indentation)
@return {ok, res} with `ok` indicating whether the execution was successful and `res` representing
the output of the interpreter (may also contain error messages)
*/
static std::pair<bool, std::string> run(const std::string& s);
/// @deprecated Use run(const std::string&, bool&) instead
BALL_DEPRECATED static String run(const String& s, bool& result);
/** Run a Python program from a file.
If the file does not exist, or cannot be opened, an Exception::FileNotFound is thrown
@param file_name the name of the program file
@deprecated Functionality replaced by Jupyter notebook plugin
*/
BALL_DEPRECATED static String runFile(const String& filename);
/**
* Calls a single function from a given module.
*
* @param module a Python module
* @param func a function from the given module
* @param params function arguments as key-value pairs
* @return true if the execution succeeded
*/
static bool execute(const std::string& module, const std::string& func, const PyKernel::KeyValArgs& params);
/**
* Returns the most recent error message emitted by the Python interpreter.
*
* @return most recent error message
*/
static std::string getErrorMessage();
/// @deprecated use execute(const string&, const string&, const KeyValArgs&) instead
BALL_DEPRECATED static bool execute(const QString& module, const QString& func, const QList<QPair<QString, QString> >& params);
//@}
/**@name Server */
//@{
/**
* Start a PyServer instance (if not already running) to allow remote execution of Python code, e.g., via
* the BALLView Jupyter kernel.
*/
static void startServer();
/**
* Stops the PyServer (if running).
*/
static void stopServer();
/**
* Indicates whether a PyServer instance is currently running.
*
* @return true if PyServer is running
*/
static bool serverIsRunning() { return bool(server_); }
//@}
protected:
static std::unique_ptr<PyKernel> kernel_;
static std::unique_ptr<PyServer> server_;
static PathStrings sys_path_;
};
} // namespace BALL
#endif // BALL_PYTHON_PYINTERPRETER_H
|