Commit 1091f6de authored by David Fairbrother's avatar David Fairbrother Committed by Gemma Guest
Browse files

Improve error handling and backwards compatibility

parent 63ecde8f
......@@ -5,9 +5,7 @@
// 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 "MantidKernel/Logger.h"
#include <boost/python/extract.hpp>
#include <boost/python/list.hpp>
......@@ -15,6 +13,13 @@
#include <boost/variant.hpp>
#include <exception>
#include <string>
#include <variant>
#include <vector>
namespace {
Mantid::Kernel::Logger g_log("Python Type Extractor");
}
namespace Mantid::PythonInterface {
......@@ -110,10 +115,19 @@ private:
propVals.reserve(values.size());
// Explicitly copy so we don't have to think about Python lifetimes with refs
std::transform(values.cbegin(), values.cend(), std::back_inserter(propVals),
[](const Mantid::PythonInterface::PyNativeTypeExtractor::PythonOutputT &varadicVal) {
return boost::get<ScalarT>(varadicVal);
});
try {
std::transform(values.cbegin(), values.cend(), std::back_inserter(propVals),
[](const Mantid::PythonInterface::PyNativeTypeExtractor::PythonOutputT &varadicVal) {
return boost::get<ScalarT>(varadicVal);
});
} catch (boost::bad_get &e) {
std::string err{
"A list with mixed types is unsupported as precision loss can occur trying to determine a common type."
" \nOriginal exception: "};
// Boost will convert bad_get into runtime_error anyway....
throw std::runtime_error(err + e.what());
}
this->operator()(std::move(propVals));
}
};
......
......@@ -37,15 +37,24 @@ public:
void operator()(std::string value) const override { m_attr.setValue(value); }
void operator()(std::vector<bool>) const override { throw std::invalid_argument(m_errorMsg); }
void operator()(std::vector<long>) const override { throw std::invalid_argument(m_errorMsg); }
void operator()(std::vector<double> value) const override { m_attr.setValue(value); }
void operator()(std::vector<long> value) const override {
// Previous existing code blindly converted any list type into a list of doubles.
// We now have to preserve this behaviour to maintain API compatibility as
// setValue only takes std::vector<double>.
std::vector<double> doubleVals;
doubleVals.reserve(value.size());
std::transform(value.cbegin(), value.cend(), std::back_inserter(doubleVals),
[](const long val) { return static_cast<double>(val); });
m_attr.setValue(std::move(doubleVals));
}
void operator()(std::vector<double> value) const override { m_attr.setValue(std::move(value)); }
void operator()(std::vector<std::string>) const override { throw std::invalid_argument(m_errorMsg); }
using Mantid::PythonInterface::IPyTypeVisitor::operator();
private:
IFunction::Attribute &m_attr;
const std::string m_errorMsg = "Invalid attribute. Allowed types=float,int,str,bool,list(float)";
const std::string m_errorMsg = "Invalid attribute. Allowed types=float,int,str,bool,list(float),list(int)";
};
/**
......
Supports Markdown
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