Skip to content

Commit

Permalink
Refs #4399. Add final declareProperty method to PythonAlgorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
martyngigg committed Mar 6, 2012
1 parent a10c5f0 commit b9c006f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ namespace Mantid
class PythonAlgorithm : public API::Algorithm
{
public:
/// Declare a specialized property
void declareProperty(Kernel::Property *prop, const std::string &doc="");
/// Declare a property using the type of the defaultValue with a validator and doc string
void declareProperty(const std::string & name, const boost::python::object & defaultValue,
const boost::python::object & validator = boost::python::object(),
Expand All @@ -60,7 +62,7 @@ namespace Mantid
void declareProperty(const std::string & name, const boost::python::object & defaultValue,
const int direction);
private:
/// Hide the base class variants as they are not required on this interface
// Hide the base class variants as they are not required on this interface
using Mantid::API::Algorithm::declareProperty;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ using namespace boost::python;

namespace
{
// declareProperty(property*,doc)
typedef void(AlgorithmWrapper::*declarePropertyType1)(Mantid::Kernel::Property*, const std::string &);
// declareProperty(name, defaultValue, validator, doc, direction)
typedef void(AlgorithmWrapper::*declarePropertyType1)(const std::string &, const boost::python::object &,
typedef void(AlgorithmWrapper::*declarePropertyType2)(const std::string &, const boost::python::object &,
const boost::python::object &, const std::string &, const int);
// declareProperty(name, defaultValue, doc, direction)
typedef void(AlgorithmWrapper::*declarePropertyType2)(const std::string &, const boost::python::object &,
typedef void(AlgorithmWrapper::*declarePropertyType3)(const std::string &, const boost::python::object &,
const std::string &, const int);
// declareProperty(name, defaultValue, direction)
typedef void(AlgorithmWrapper::*declarePropertyType3)(const std::string &, const boost::python::object &, const int);
typedef void(AlgorithmWrapper::*declarePropertyType4)(const std::string &, const boost::python::object &, const int);

// Overload types
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(declarePropertyType1_Overload, declareProperty, 2, 5);
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(declarePropertyType2_Overload, declareProperty, 3, 4);
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(declarePropertyType1_Overload, declareProperty, 1, 2);
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(declarePropertyType2_Overload, declareProperty, 2, 5);
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(declarePropertyType3_Overload, declareProperty, 3, 4);
}

void export_leaf_classes()
Expand All @@ -38,16 +41,19 @@ void export_leaf_classes()
// Export the algorithm wrapper that boost.python makes look like a PythonAlgorithm
class_<AlgorithmWrapper, bases<Algorithm>, boost::noncopyable>("PythonAlgorithm", "Base class for all Python algorithms")
.def("declareProperty", (declarePropertyType1)&AlgorithmWrapper::declareProperty,
declarePropertyType1_Overload(args("name", "defaultValue", "validator=None","doc=''","direction=Direction.Input"),
declarePropertyType1_Overload(args("prop", "doc")))

.def("declareProperty", (declarePropertyType2)&AlgorithmWrapper::declareProperty,
declarePropertyType2_Overload(args("name", "defaultValue", "validator=None","doc=''","direction=Direction.Input"),
"Declares a named property where the type is taken from "
"the type of the defaultValue and mapped to an appropriate C++ type"))

.def("declareProperty", (declarePropertyType2)&AlgorithmWrapper::declareProperty,
declarePropertyType2_Overload(args("name", "defaultValue", "doc","direction=Direction.Input"),
.def("declareProperty", (declarePropertyType3)&AlgorithmWrapper::declareProperty,
declarePropertyType3_Overload(args("name", "defaultValue", "doc","direction=Direction.Input"),
"Declares a named property where the type is taken from the type "
"of the defaultValue and mapped to an appropriate C++ type"))

.def("declareProperty", (declarePropertyType3)&AlgorithmWrapper::declareProperty,
.def("declareProperty", (declarePropertyType4)&AlgorithmWrapper::declareProperty,
args("name", "defaultValue", "direction"),
"Declares a named property where the type is taken from the type of "
"the defaultValue and mapped to an appropriate C++ type")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ namespace Mantid
{
namespace PythonInterface
{

/**
* Declare a preconstructed property
* @param prop :: A pointer to a property
* @param doc :: An optional doc string
*/
void PythonAlgorithm::declareProperty(Kernel::Property *prop, const std::string & doc)
{
// We need to clone the property so that python doesn't own the object that gets inserted
// into the manager
Algorithm::declareProperty(prop->clone(), doc);
}

/**
* Declare a property using the type of the defaultValue, a documentation string and validator
* @param name :: The name of the new property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import testhelpers

from mantid import PythonAlgorithm, Direction
from mantid import BoundedValidator
from mantid import BoundedValidator, FileProperty, FileAction


class BasicPropsAlg(PythonAlgorithm):
Expand Down Expand Up @@ -86,5 +86,32 @@ def PyExec(self):
self.assertRaises(ValueError, alg.setProperty, "NumPropWithDefaultDir", -10)
testhelpers.assert_raises_nothing(self, alg.setProperty, "NumPropWithDefaultDir", 11)

def test_specialized_property_declaration(self):
"""
Test property declaration using a specialised property.
The property types should have their own tests too.
"""
class SpecializedProperties(PythonAlgorithm):

_testdocstring = 'This is a FileProperty'
def PyInit(self):
self.declareProperty(FileProperty("NoDocString", "", FileAction.Load))
self.declareProperty(FileProperty("WithDocString", "", FileAction.Load), self._testdocstring)

def PyExec(self):
pass
####################################################
alg = SpecializedProperties()
alg.initialize()
props = alg.getProperties()
self.assertEquals(2, len(props))

nodoc = alg.getProperty("NoDocString")
self.assertTrue(isinstance(nodoc, FileProperty))
self.assertEquals("", nodoc.documentation)
withdoc = alg.getProperty("WithDocString")
self.assertTrue(isinstance(withdoc, FileProperty))
self.assertEquals(alg._testdocstring, withdoc.documentation)

if __name__ == '__main__':
unittest.main()

0 comments on commit b9c006f

Please sign in to comment.