Skip to content

Commit

Permalink
Add Python exports to create AlgorithmProperty from Python.
Browse files Browse the repository at this point in the history
Required to match behavour with old API.
Refs #7469
  • Loading branch information
martyngigg committed Jul 23, 2013
1 parent 94b0abc commit 570ec2f
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,41 @@
#include "MantidAPI/IAlgorithm.h"
#include "MantidPythonInterface/kernel/PropertyWithValue.h"
#include <boost/python/class.hpp>
#include <boost/python/make_constructor.hpp>

using Mantid::API::AlgorithmProperty;
using Mantid::API::IAlgorithm;
using Mantid::Kernel::IValidator;
using Mantid::Kernel::PropertyWithValue;
using namespace boost::python;

namespace
{
/**
* Factory function for creating an input property with a validator and a direction
* @param name The name of the property
* @param validator A pointer to the validator passed from Python. It is cloned when passed to the framework
* @param direction An output/input/inout property
* @return A pointer to a new AlgorithmProperty object
*/
AlgorithmProperty * createPropertyWithValidatorAndDirection(const std::string &name, IValidator *validator, unsigned int direction)
{
return new AlgorithmProperty(name, validator->clone(), direction);
}

/**
* Factory function for creating an input property with a validator
* @param name The name of the property
* @param validator A pointer to the validator passed from Python. It is cloned when passed to the framework
* @return A pointer to a new AlgorithmProperty object
*/
AlgorithmProperty * createPropertyWithValidator(const std::string &name, IValidator *validator)
{
return createPropertyWithValidatorAndDirection(name, validator, Mantid::Kernel::Direction::Input);
}

}

void export_AlgorithmProperty()
{
// AlgorithmProperty has base PropertyWithValue<boost::shared_ptr<IAlgorithm>>
Expand All @@ -16,6 +45,12 @@ void export_AlgorithmProperty()
EXPORT_PROP_W_VALUE(HeldType, IAlgorithm);

class_<AlgorithmProperty, bases<PropertyWithValue<HeldType>>, boost::noncopyable>("AlgorithmProperty", no_init)
.def(init<const std::string &>(args("name")))
// These variants require the validator object to be cloned
.def("__init__", make_constructor(&createPropertyWithValidator,
default_call_policies(), args("name", "validator")))
.def("__init__", make_constructor(&createPropertyWithValidatorAndDirection,
default_call_policies(), args("name", "validator", "direction")))
;
}

Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,34 @@ void export_Property()

// Add properties as that's what old version had
class_<Property, boost::noncopyable>("Property", no_init)
.add_property("name", make_function(&Mantid::Kernel::Property::name, return_value_policy<copy_const_reference>()),
.add_property("name", make_function(&Property::name, return_value_policy<copy_const_reference>()),
"The name of the property")

.add_property("isValid", make_function(&Mantid::Kernel::Property::isValid),
.add_property("isValid", make_function(&Property::isValid),
"An empty string if the property is valid, otherwise it contains an error message.")

.add_property("isDefault", make_function(&Mantid::Kernel::Property::isDefault), "Is the property set at the default value")
.add_property("isDefault", make_function(&Property::isDefault), "Is the property set at the default value")

.add_property("getDefault", make_function(&Mantid::Kernel::Property::getDefault), "Get the default value as a string")
.add_property("getDefault", make_function(&Property::getDefault), "Get the default value as a string")

.add_property("direction", &Mantid::Kernel::Property::direction,
.add_property("direction", &Property::direction,
"Input, Output, InOut or Unknown. See the Direction class")

.add_property("documentation", make_function(&Mantid::Kernel::Property::documentation, return_value_policy<copy_const_reference>()),
.add_property("documentation", make_function(&Property::documentation, return_value_policy<copy_const_reference>()),
"The property's doc string")

.add_property("type", make_function(&Mantid::Kernel::Property::type), "Returns a string identifier for the type")
.add_property("type", make_function(&Property::type), "Returns a string identifier for the type")

.add_property("units", make_function(&Mantid::Kernel::Property::units, return_value_policy<copy_const_reference>()),
.add_property("units", make_function(&Property::units, return_value_policy<copy_const_reference>()),
"The units attached to this property")

.add_property("valueAsStr", &Mantid::Kernel::Property::value, "The value of the property as a string. "
.add_property("valueAsStr", &Property::value, &Property::setValue, "The value of the property as a string. "
"For some property types, e.g. Workspaces, it is useful to be able to refer to the string value directly")

.add_property("allowedValues", &Mantid::Kernel::Property::allowedValues, "A list of allowed values")
.add_property("allowedValues", &Property::allowedValues, "A list of allowed values")

.add_property("getGroup", make_function(&Mantid::Kernel::Property::getGroup, return_value_policy<copy_const_reference>()),
.add_property("getGroup", make_function(&Property::getGroup, return_value_policy<copy_const_reference>()),
"Return the 'group' of the property, that is, the header in the algorithm's list of properties.")

;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import unittest
from mantid.api import AlgorithmProperty, IAlgorithm
from mantid.kernel import Direction

class AlgorithmPropertyTest(unittest.TestCase):

def test_construction_with_name_produces_input_property(self):
prop = AlgorithmProperty("TestProperty")

self.assertEquals(Direction.Input, prop.direction)

def test_value_method_returns_an_algorithm_type(self):
prop = AlgorithmProperty("TestProperty")
prop.valueAsStr = 'CreateWorkspace(OutputWorkspace="ws",DataY="1",DataX="1",NSpec=1'

alg = prop.value
self.assertTrue(isinstance(alg,IAlgorithm))
self.assertEquals("CreateWorkspace",alg.name())


if __name__ == '__main__':
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set ( TEST_PY_FILES
AlgorithmTest.py
AlgorithmFactoryTest.py
AlgorithmManagerTest.py
AlgorithmPropertyTest.py
AnalysisDataServiceTest.py
AxisTest.py
DeprecatedAlgorithmCheckerTest.py
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ def setUp(self):
self.__class__._mask_dets = AlgorithmManager.createUnmanaged("MaskDetectors")
self.__class__._mask_dets.initialize()

def test_value_setting_as_string_gives_expected_value_for_correct_type(self):
prop = self.__class__._integration.getProperty("RangeLower")
prop.valueAsStr = "15.5"

self.assertAlmostEqual(15.5, prop.value)

def test_type_str_is_not_empty(self):
rangeLower=self.__class__._integration.getProperty("RangeLower")
self.assertTrue(len(rangeLower.type) > 0)
Expand Down

0 comments on commit 570ec2f

Please sign in to comment.