Mantid
Loading...
Searching...
No Matches
Property.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
14#include <array>
15
16#include <boost/python/class.hpp>
17#include <boost/python/copy_const_reference.hpp>
18#include <boost/python/def.hpp>
19#include <boost/python/dict.hpp>
20#include <boost/python/enum.hpp>
21#include <boost/python/implicit.hpp>
22#include <boost/python/list.hpp>
23#include <boost/python/make_function.hpp>
24#include <boost/python/overloads.hpp>
25#include <boost/python/register_ptr_to_python.hpp>
26#include <boost/python/return_value_policy.hpp>
27
31using namespace boost::python;
32
33namespace {
34
35//
36// gcc 7 with std=c++17 has an issue attaching the EMPTY_*
37// functions with add_static_property when attempting to cast
38// the function pointer to a "const volatile void *":
39//
40// arg_to_python.hpp:211:66: error: invalid conversion from 'double (*)()
41// noexcept'
42// to 'const volatile void*' [-fpermissive]
43//
44// The noexcept specification appears to prevent the cast in the
45// boost python layer. These functions provide a pass through without the
46// noexcept specifier.
47
48constexpr inline double emptyDouble() { return Mantid::EMPTY_DBL(); }
49
50constexpr inline int emptyInt() { return Mantid::EMPTY_INT(); }
51
52constexpr inline long emptyLong() { return Mantid::EMPTY_LONG(); }
53
59PyObject *unitAsUnicode(const Property &self) {
60 static constexpr std::array<const char *, 2> codecs{"utf-8", "windows-1252"};
61 const auto &unitsBytes = self.units();
62 for (const auto &encoding : codecs) {
63 auto unitsPy = PyUnicode_Decode(unitsBytes.c_str(), unitsBytes.size(), encoding, "strict");
64 if (unitsPy)
65 return unitsPy;
66 // encoding failed. Try next
67 PyErr_Clear();
68 }
69 // All attempts failed, create an appropriate error string
70 const std::string allCodecsStr = []() {
71 auto it = codecs.begin();
72 std::string result = *it++;
73 for (; it != codecs.end(); ++it) {
74 result.append(",");
75 result.append(*it);
76 }
77 return result;
78 }();
79 const std::string helpMessage = std::string("Can't decode units string. Tried codecs=")
80 .append(allCodecsStr)
81 .append("\nTo try other codecs use Property.unitsAsBytes to retrieve the "
82 "original bytes object and use .decode().");
83 PyErr_SetString(PyExc_RuntimeError, helpMessage.c_str());
84 throw error_already_set();
85}
86
92PyObject *unitsAsBytes(const Property &self) { return PyBytes_FromString(self.units().c_str()); }
93
94} // namespace
95
97GNU_DIAG_OFF("unused-local-typedef")
98// Ignore -Wconversion warnings coming from boost::python
99// Seen with GCC 7.1.1 and Boost 1.63.0
100GNU_DIAG_OFF("conversion")
101
102BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(valueAsPrettyStrOverloader,
103
104 valueAsPrettyStr, 0, 2)
105GNU_DIAG_ON("conversion")
106GNU_DIAG_ON("unused-local-typedef")
107
108void export_Property() {
109 register_ptr_to_python<Property *>();
110
111 // vector of properties
112 std_vector_exporter<Property *>::wrap("std_vector_property");
113
114 // Direction
115 enum_<Direction::Type>("Direction")
116 .value("Input", Direction::Input)
117 .value("Output", Direction::Output)
118 .value("InOut", Direction::InOut)
119 .value("None", Direction::None);
120
121 // Add properties as that's what old version had
122 class_<Property, boost::noncopyable>("Property", no_init)
123 .add_property("name", make_function(&Property::name, return_value_policy<copy_const_reference>()),
124 "The name of the property")
125
126 .add_property("isValid", make_function(&Property::isValid),
127 "An empty string if the property is valid, otherwise it "
128 "contains an error message.")
129
130 .add_property("isDefault", make_function(&Property::isDefault), "Is the property set at the default value")
131
132 .add_property("getDefault", make_function(&Property::getDefault), "Get the default value as a string")
133
134 .add_property("direction", &Property::direction, "Input, Output, InOut or Unknown. See the Direction class")
135
136 .add_property("documentation",
137 make_function(&Property::documentation, return_value_policy<copy_const_reference>()),
138 "The property's doc string")
139
140 .add_property("type", make_function(&Property::type), "Returns a string identifier for the type")
141
142 .add_property("units", &unitAsUnicode, &Property::setUnits, "The units attached to this property")
143
144 .add_property("unitsAsBytes", &unitsAsBytes,
145 "The units attached to this property as a encoded bytes object. It "
146 "is assumed the caller knows the correct endcoding used.")
147
148 .add_property("valueAsStr", &Property::value, &Property::setValue,
149 "The value of the property as a string. "
150 "For some property types, e.g. Workspaces, it is useful to "
151 "be able to refer to the string value directly")
152
153 .def("valueAsPrettyStr", &Property::valueAsPrettyStr,
154 valueAsPrettyStrOverloader((arg("maxLength") = 0, arg("collapseLists") = true),
155 "The value of the property as a formatted string. "
156 "If maxLength is defined then the output may not contain the "
157 "full "
158 "contents of the property. The maxLength and collapseLists "
159 "arguments "
160 "do not work for all property types"))
161
162 .add_property("allowedValues", &Property::allowedValues, "A list of allowed values")
163
164 .add_property("getGroup", make_function(&Property::getGroup, return_value_policy<copy_const_reference>()),
165 "Return the 'group' of the property, that is, the header "
166 "in the algorithm's list of properties.")
167
168 .add_property("settings", make_function(&Property::getSettings, return_value_policy<return_by_value>()),
169 "Return the object managing this property's settings")
170
171 .add_static_property("EMPTY_DBL", emptyDouble)
172 .add_static_property("EMPTY_INT", emptyInt)
173 .add_static_property("EMPTY_LONG", emptyLong)
174
175 .def("setAutoTrim", &Property::setAutoTrim, (arg("setting")), "Setting automatic trimming of whitespaces.")
176 .def("getAutoTrim", &Property::autoTrim, "Gets the setting of automatic trimming of whitespaces.");
177}
#define GET_POINTER_SPECIALIZATION(TYPE)
Definition: GetPointer.h:17
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(valueAsPrettyStrOverloader, valueAsPrettyStr, 0, 2) void export_Property()
Definition: Property.cpp:102
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Base class for properties.
Definition: Property.h:94
virtual const std::string & units() const
Returns the units of the property, if any, as a string.
Definition: Property.cpp:179
IPropertySettings * getSettings()
Definition: Property.cpp:98
virtual std::string valueAsPrettyStr(const size_t maxLength=0, const bool collapseLists=true) const
Returns the value of the property as a pretty printed string.
Definition: Property.cpp:123
bool autoTrim() const
Returns if the property is set to automatically trim string unput values of whitespace.
Definition: Property.cpp:364
unsigned int direction() const
returns the direction of the property
Definition: Property.h:172
const std::string & documentation() const
Get the property's documentation string.
Definition: Property.cpp:65
virtual std::string setValue(const std::string &)=0
Set the value of the property via a string.
virtual void setUnits(const std::string &unit)
Sets the units of the property, as a string.
Definition: Property.cpp:186
virtual std::string isValid() const
Overridden function that checks whether the property, if not overriden returns "".
Definition: Property.cpp:82
virtual bool isDefault() const =0
Overriden function that returns if property has the same value that it was initialised with,...
const std::string & name() const
Get the property's name.
Definition: Property.cpp:60
void setAutoTrim(const bool &setting)
Sets if the property is set to automatically trim string unput values of whitespace.
Definition: Property.cpp:371
const std::string & getGroup()
Definition: Property.h:197
virtual std::vector< std::string > allowedValues() const
Returns the set of valid values for this property, if such a set exists.
Definition: Property.cpp:140
const std::string type() const
Returns the type of the property as a string.
Definition: Property.cpp:76
virtual std::string getDefault() const =0
Get the default value for the property which is the value the property was initialised with.
virtual std::string value() const =0
Returns the value of the property as a string.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition: EmptyValues.h:25
constexpr long EMPTY_LONG() noexcept
Returns what we consider an "empty" long within a property.
Definition: EmptyValues.h:31
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition: EmptyValues.h:43
Describes the direction (within an algorithm) of a Property.
Definition: Property.h:50
@ InOut
Both an input & output workspace.
Definition: Property.h:55
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54
A struct to help export std::vector types.
static void wrap(std::string const &python_name)
a python wrapper