16#include <boost/python/class.hpp>
17#include <boost/python/dict.hpp>
20auto PYALG_STRUCTURE_DOCS =
"https://docs.mantidproject.org/tutorials/extending_mantid_with_python/"
21 "python_algorithms/01_basic_algorithm_structure.html#basic-algorithm-structure";
34template <
typename BaseAlgorithm>
36 : BaseAlgorithm(),
m_self(self), m_isRunningObj(nullptr), m_wikiSummary(
"") {
48 return std::string(getSelf()->ob_type->tp_name);
57 return callMethod<int>(getSelf(),
"version");
70 return callMethod<bool>(getSelf(),
"checkGroups");
72 return BaseAlgorithm::checkGroups();
81 const static std::string defaultCategory =
"PythonAlgorithms";
82 std::string category = defaultCategory;
84 category = callMethod<std::string>(getSelf(),
"category");
87 if (category == defaultCategory) {
89 this->getLogger().warning() <<
"Python Algorithm " << this->
name() <<
" v" << this->version()
90 <<
" does not have a category defined. See " << PYALG_STRUCTURE_DOCS <<
"\n";
115 return callMethod<std::string>(getSelf(),
"alias");
117 return BaseAlgorithm::alias();
127 return callMethod<std::string>(getSelf(),
"aliasDeprecated");
129 return BaseAlgorithm::aliasDeprecated();
139 return callMethod<std::string>(getSelf(),
"summary");
141 return m_wikiSummary;
150 return callMethod<std::string>(getSelf(),
"helpURL");
152 return std::string();
160 if (!m_isRunningObj) {
161 return SuperClass::isRunning();
166 PyObject *result = PyObject_CallObject(m_isRunningObj,
nullptr);
167 if (PyErr_Occurred())
169 if (PyBool_Check(result)) {
170 return static_cast<bool>(PyLong_AsLong(result));
172 throw std::runtime_error(
"Algorithm.isRunning - Expected bool return type.");
179 return callMethod<void>(getSelf(),
"cancel");
181 SuperClass::cancel();
189 using boost::python::dict;
190 std::map<std::string, std::string> resultMap;
194 dict resultDict = callMethod<dict>(getSelf(),
"validateInputs");
196 boost::python::list keys = resultDict.keys();
197 size_t numItems = boost::python::len(keys);
198 for (
size_t i = 0; i < numItems; ++i) {
199 boost::python::object key = keys[i];
200 boost::python::object
value = resultDict[key];
203 std::string keyAsString = boost::python::extract<std::string>(key);
204 std::string valueAsString = boost::python::extract<std::string>(
value);
205 resultMap[std::move(keyAsString)] = std::move(valueAsString);
206 }
catch (boost::python::error_already_set &) {
207 this->getLogger().error() <<
"In validateInputs(self): Invalid type for key/value pair "
208 <<
"detected in dict.\n"
209 <<
"All keys and values must be strings\n";
223 std::string msg =
"self.setWikiSummary() is deprecated and will be removed in a future "
225 "To ensure continued functionality remove the line containing "
226 "'self.setWikiSummary'\n"
227 "and add a new function outside of the current one defined like so:\n"
228 "def summary(self):\n"
232 PyErr_Warn(PyExc_DeprecationWarning, msg.c_str());
233 m_wikiSummary = summary;
242template <
typename BaseAlgorithm>
244 const std::string &doc) {
245 BaseAlgorithm &caller = extract<BaseAlgorithm &>(self);
249 caller.declareProperty(std::unique_ptr<Kernel::Property>(prop->
clone()), doc);
264template <
typename BaseAlgorithm>
266 const boost::python::object &defaultValue,
267 const boost::python::object &validator,
268 const std::string &doc,
const int direction) {
269 BaseAlgorithm &caller = extract<BaseAlgorithm &>(self);
270 auto prop = std::unique_ptr<Kernel::Property>(
272 caller.declareProperty(std::move(prop), doc);
285template <
typename BaseAlgorithm>
287 const boost::python::object &defaultValue,
288 const std::string &doc,
const int direction) {
289 BaseAlgorithm &caller = extract<BaseAlgorithm &>(self);
292 caller.declareProperty(std::move(prop), doc);
303template <
typename BaseAlgorithm>
305 const boost::python::object &defaultValue,
306 const int direction) {
307 declarePyAlgProperty(self,
name, defaultValue,
"", direction);
322template <
typename BaseAlgorithm>
324 const std::string &
name,
325 const boost::python::object &defaultValue,
326 const boost::python::object &validator,
327 const std::string &doc,
const int direction) {
328 BaseAlgorithm &caller = extract<BaseAlgorithm &>(self);
329 auto prop = std::unique_ptr<Kernel::Property>(
331 caller.declareOrReplaceProperty(std::move(prop), doc);
343 callMethod<void>(getSelf(),
"PyInit");
352 callMethod<void>(getSelf(),
"PyExec");
354 if (BaseAlgorithm::getCancel())
double value
The value of the point.
std::unique_ptr< ConceptT > m_self
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
CancelException is thrown to cancel execution of the algorithm.
Base class for properties.
virtual Property * clone() const =0
'Virtual copy constructor'
Provides a layer class for boost::python to allow C++ virtual functions to be overridden in a Python ...
const std::string helpURL() const override
Optional documentation URL of the algorithm, empty string if not overridden.
void setWikiSummary(const std::string &summary)
Set the summary text.
void cancel() override
Allow the cancel method to be overridden.
std::map< std::string, std::string > validateInputs() override
Returns the validateInputs result of the algorithm.
AlgorithmAdapter()=delete
Disable default constructor - The PyObject must be supplied to construct the object.
const std::string alias() const override
Allow the method returning the algorithm aliases to be overridden.
static void declareOrReplacePyAlgProperty(boost::python::object &self, const std::string &name, const boost::python::object &defaultValue, const boost::python::object &validator=boost::python::object(), const std::string &doc="", const int direction=Kernel::Direction::Input)
Declare or replace a property using the type of the defaultValue with a validator and doc string.
const std::string name() const override
Returns the name of the algorithm.
PyObject * m_isRunningObj
A pointer to an overridden isRunning method.
bool checkGroups() override
A return of false will allow processing workspace groups as a whole.
const std::string aliasDeprecated() const override
Returns optional documentation URL of the algorithm.
const std::string summary() const override
Returns the summary for the algorithm.
void exec() override
Private exec for this algorithm.
int version() const override
Returns a version of the algorithm.
const std::vector< std::string > seeAlso() const override
Returns seeAlso related algorithms.
static void declarePyAlgProperty(boost::python::object &self, Kernel::Property *prop, const std::string &doc="")
Declare a preconstructed property.
const std::string category() const override
Returns a category of the algorithm.
void init() override
Private init for this algorithm.
bool isRunning() const override
Allow the isRunning method to be overridden.
Defines a structure for acquiring/releasing the Python GIL using the RAII pattern.
Exception type that captures the current Python error state as a generic C++ exception for any genera...
static std::unique_ptr< Kernel::Property > create(const std::string &name, const boost::python::object &defaultValue, const boost::python::object &validator, const unsigned int direction)
Creates a PropertyWithValue<Type> instance from the given information.
bool MANTID_PYTHONINTERFACE_CORE_DLL typeHasAttribute(PyObject *obj, const char *attr)
This namespace contains helper functions for classes that are overridden in Python.
Converts a Python sequence type to a C++ std::vector, where the element type is defined by the templa...
Defines an exception for an undefined attribute.