Commit ee55dd6e authored by Gemma Guest's avatar Gemma Guest
Browse files

Move python types extractor into core converters

parent 979c472a
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2021 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
#include <string>
#include <variant>
#include <vector>
#include <boost/python/extract.hpp>
#include <boost/python/object.hpp>
#include <exception>
namespace Mantid::PythonInterface {
struct PyNativeTypeExtractor {
using PythonOutputT = std::variant<bool, int, double, std::string>;
static PythonOutputT convert(const boost::python::object &obj) {
using namespace boost::python;
const PyObject *rawptr = obj.ptr();
PythonOutputT out;
// This currently doesn't handle lists, but this could be retrofitted in future work
if (PyBool_Check(rawptr) == 1) {
bool val = extract<bool>(obj);
out = val;
} else if (PyFloat_Check(rawptr) == 1) {
double val = extract<double>(obj);
out = val;
} else if (PyLong_Check(rawptr) == 1) {
int val = extract<int>(obj);
out = val;
} else if (PyUnicode_Check(rawptr)) {
std::string val = extract<std::string>(obj);
out = val;
} else {
throw std::invalid_argument("Unrecognised Python type");
}
return out;
}
};
} // namespace Mantid::PythonInterface
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(default : 4250) #pragma warning(default : 4250)
#endif #endif
#include "MantidPythonInterface/core/Converters/PyNativeTypeExtractor.h"
#include "MantidPythonInterface/core/GetPointer.h" #include "MantidPythonInterface/core/GetPointer.h"
#include <boost/optional.hpp> #include <boost/optional.hpp>
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
#include <boost/python/scope.hpp> #include <boost/python/scope.hpp>
#include <cstddef> #include <cstddef>
#include <variant>
using Mantid::API::Algorithm; using Mantid::API::Algorithm;
using Mantid::API::DistributedAlgorithm; using Mantid::API::DistributedAlgorithm;
...@@ -97,9 +99,24 @@ template <typename T> void extractKwargs(const dict &kwargs, const std::string & ...@@ -97,9 +99,24 @@ template <typename T> void extractKwargs(const dict &kwargs, const std::string &
} }
} }
class SetPropertyVisitor {
public:
SetPropertyVisitor(Mantid::API::Algorithm_sptr &alg, std::string const &propName)
: m_alg(alg), m_propName(propName) {}
void operator()(bool value) { m_alg->setProperty(m_propName, value); }
void operator()(int value) { m_alg->setProperty(m_propName, value); }
void operator()(double value) { m_alg->setProperty(m_propName, value); }
void operator()(std::string const &value) { m_alg->setPropertyValue(m_propName, value); }
private:
Mantid::API::Algorithm_sptr &m_alg;
std::string const &m_propName;
};
// Signature createChildWithProps(self, name, startProgress, endProgress, enableLogging, version, **kwargs) // Signature createChildWithProps(self, name, startProgress, endProgress, enableLogging, version, **kwargs)
object createChildWithProps(tuple args, dict kwargs) { object createChildWithProps(tuple args, dict kwargs) {
std::shared_ptr<Algorithm> parentAlg = extract<std::shared_ptr<Algorithm>>(args[0]); Mantid::API::Algorithm_sptr parentAlg = extract<Mantid::API::Algorithm_sptr>(args[0]);
auto name = extractArg<std::string>(1, args); auto name = extractArg<std::string>(1, args);
auto startProgress = extractArg<double>(2, args); auto startProgress = extractArg<double>(2, args);
auto endProgress = extractArg<double>(3, args); auto endProgress = extractArg<double>(3, args);
...@@ -132,21 +149,10 @@ object createChildWithProps(tuple args, dict kwargs) { ...@@ -132,21 +149,10 @@ object createChildWithProps(tuple args, dict kwargs) {
if (!curArg) if (!curArg)
continue; continue;
const PyObject *rawptr = curArg.ptr(); using Mantid::PythonInterface::PyNativeTypeExtractor;
auto nativeObj = PyNativeTypeExtractor::convert(curArg);
// This currently doesn't handle lists, but this could be retrofitted in future work
if (PyBool_Check(rawptr) == 1) { std::visit(SetPropertyVisitor(childAlg, propName), nativeObj);
bool val = extract<bool>(curArg);
childAlg->setProperty(propName, val);
} else if (PyFloat_Check(rawptr) == 1) {
double val = extract<double>(curArg);
childAlg->setProperty(propName, val);
} else if (PyLong_Check(rawptr) == 1) {
int val = extract<int>(curArg);
childAlg->setProperty(propName, val);
} else {
childAlg->setPropertyValue(propName, extract<std::string>(curArg));
}
} }
return object(childAlg); return object(childAlg);
} }
......
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