Skip to content

Commit

Permalink
Refs #4399. Exported the WorkspaceProperty constructors.
Browse files Browse the repository at this point in the history
  • Loading branch information
martyngigg committed Mar 7, 2012
1 parent 0422162 commit 8f0376a
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 8 deletions.
2 changes: 2 additions & 0 deletions Code/Mantid/Framework/PythonInterface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ set ( TEST_PY_FILES
test/python/PropertyWithValueTest.py
test/python/PythonAlgorithmPropertiesTest.py
test/python/PythonAlgorithmTraitsTest.py
test/python/PythonAlgorithmWorkspacePropertyTest.py
test/python/ReferenceFrameTest.py
test/python/RunTest.py
test/python/SimpleAPITest.py
Expand All @@ -105,6 +106,7 @@ set ( TEST_PY_FILES
test/python/UnitCellTest.py
test/python/WorkspaceTest.py
test/python/WorkspaceGroupTest.py
test/python/WorkspacePropertiesTest.py
)

set ( PYTEST_HELPERS test/python/testhelpers.py )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,122 @@
#include "MantidPythonInterface/kernel/PropertyWithValue.h"
#include "MantidAPI/WorkspaceProperty.h"
#include <boost/python/register_ptr_to_python.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/python/args.hpp>

namespace Mantid
{
namespace PythonInterface
{
/**
* A helper struct to export WorkspaceProperty<> types to Python. It also
* exports a new PropertyWithValue<WorkspaceType> type as this is required to
* for the base class.
*/
template<typename WorkspaceType>
struct WorkspacePropertyExporter
{
/// The export type
typedef Mantid::API::WorkspaceProperty<WorkspaceType> TypedWorkspaceProperty;
/// Shared pointer to Worksapce type
typedef boost::shared_ptr<WorkspaceType> WorkspaceType_sptr;

/**
* Factory function to act as a constructor so that the validator can be cloned
* rather than passing in the python owned object
* @param name :: The name of the property
* @param wsName :: A default value
* @param direction :: The direction, @see Direction enum
* @param validator :: A pointer validator object
*/
static TypedWorkspaceProperty *
createPropertyWithValidator(const std::string &name, const std::string &wsName,
const unsigned int direction,
Kernel::IValidator<WorkspaceType_sptr> * validator)
{
return new TypedWorkspaceProperty(name, wsName, direction, validator->clone());
}

/**
* Factory function to act as a constructor so that the validator can be cloned
* rather than passing in the python owned object
* @param name :: The name of the property
* @param wsName :: A default value
* @param direction :: The direction, @see Direction enum
* @param optional :: If true then the workspace is optional
* @param validator :: A pointer validator object
*/
static TypedWorkspaceProperty *
createPropertyWithOptionalFlag(const std::string &name, const std::string &wsName,
const unsigned int direction, bool optional,
Kernel::IValidator<WorkspaceType_sptr> * validator)
{
return new TypedWorkspaceProperty(name, wsName, direction, optional, validator->clone());
}

/**
* Factory function to act as a constructor so that the validator can be cloned
* rather than passing in the python owned object
* @param name :: The name of the property
* @param wsName :: A default value
* @param direction :: The direction, @see Direction enum
* @param validator :: A pointer validator object
* @param optional :: If true then the workspace is optional
* @param locking :: If true then the workspace will be locked before running an algorithm
*/
static TypedWorkspaceProperty *
createPropertyWithLockFlag(const std::string &name, const std::string &wsName,
const unsigned int direction,
bool optional, bool locking,
Kernel::IValidator<WorkspaceType_sptr> * validator)
{
return new TypedWorkspaceProperty(name, wsName, direction, optional, locking,validator->clone());
}

/**
* Defines the necessary exports for a WorkspaceProperty<WorkspaceType>
* @param pythonClassName :: The name of the class in python
*/
static void define(const char * pythonClassName)
{
using namespace boost::python;
using Mantid::API::IWorkspaceProperty;
using Mantid::Kernel::PropertyWithValue;

EXPORT_PROP_W_VALUE(WorkspaceType_sptr, WorkspaceType);
register_ptr_to_python<TypedWorkspaceProperty*>();

class_<TypedWorkspaceProperty, bases<PropertyWithValue<WorkspaceType_sptr>, IWorkspaceProperty>,
boost::noncopyable>(pythonClassName, no_init)
.def(init<const std::string &, const std::string &, const unsigned int
>(args("name","defaultValue", "direction")))
.def(init<const std::string &, const std::string &, const unsigned int,
bool>(args("name","defaultValue", "direction", "optional")))
.def(init<const std::string &, const std::string &, const unsigned int,
bool, bool>(args("name","defaultValue", "direction", "optional", "locking")))
// These variants require the validator object to be cloned
.def("__init__", make_constructor(&createPropertyWithValidator,
default_call_policies(), args("name","defaultValue", "direction", "validator")))
.def("__init__", make_constructor(&createPropertyWithOptionalFlag,
default_call_policies(),
args("name","defaultValue", "direction", "optional", "validator")))
.def("__init__", make_constructor(&createPropertyWithLockFlag,
default_call_policies(),
args("name","defaultValue", "direction", "optional", "locking", "validator")))
;

}
};
}
}

/**
* Defines a macro for exporting new WorkspaceProperty types.
* This automatically exports a new PropertyWithValue class for the given type.
*
* @param Type :: The workspace type (not the shared_ptr wrapped type)
* @param ClassName :: A string defining the final class name in Python
*/
#define EXPORT_WORKSPACE_PROPERTY(Type, ClassName) \
EXPORT_PROP_W_VALUE(boost::shared_ptr<Type>, Type); \
boost::python::register_ptr_to_python<Mantid::API::WorkspaceProperty<Type>*>(); \
boost::python::class_<Mantid::API::WorkspaceProperty<Type>,\
boost::python::bases<Mantid::Kernel::PropertyWithValue<boost::shared_ptr<Type> >, Mantid::API::IWorkspaceProperty>,\
boost::noncopyable>(ClassName, boost::python::no_init) \
;
Mantid::PythonInterface::WorkspacePropertyExporter<Type>::define(ClassName);

#endif /* MANTID_PYTHONINTERFACE_WORKSPACEPROPERTYMACRO_H_ */
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""Defines tests for the simple property declarations types within
Python algorithms
"""

import unittest
import testhelpers

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""Defines tests for the traits within Python algorithms
such as name, version etc.
"""

import unittest
import testhelpers
from mantid import (PythonAlgorithm, AlgorithmProxy, Algorithm, IAlgorithm,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Defines tests for the WorkspaceProperty types within
Python algorithms
"""
import unittest
from mantid.api import PythonAlgorithm, WorkspaceProperty
from mantid.kernel import Direction

class PythonAlgorithmWorkspacePropertyTest(unittest.TestCase):

def _do_test(self, classtype):
"""Perform the test for the given type
@param classtype :: The property class to declare
"""
class WorkspaceProperties(PythonAlgorithm):

_testdocstring = 'This is a workspace property'
def PyInit(self):
self.declareProperty(classtype("NoDocString", "", Direction.Input))
self.declareProperty(classtype("WithDocString", "", Direction.Input), self._testdocstring)

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

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

def test_alg_accepts_WorkspaceProperty_declaration(self):
"""Runs test for a general WorkspaceProperty
"""
self._do_test(WorkspaceProperty)

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Tests the construction of the various workspace
property types
"""
import unittest
import testhelpers
from mantid.api import (WorkspaceProperty, MatrixWorkspaceProperty, IEventWorkspaceProperty,
ITableWorkspaceProperty)
from mantid.kernel import Direction

class WorkspacePropertiesTest(unittest.TestCase):

def _do_test(self, classtype):
self._do_construction_with_name_default_direction(classtype)
self._do_construction_with_name_default_direction_optional(classtype)

def _do_construction_with_name_default_direction(self, classtype):
prop = classtype("NoValidation", "test", Direction.Output)
self.assertTrue(isinstance(prop, classtype))
self.assertEquals("NoValidation", prop.name)
self.assertEquals(Direction.Output, prop.direction)
self.assertEquals("test", prop.valueAsStr)

def _do_construction_with_name_default_direction_optional(self, classtype):
prop = classtype("IsOptional", "test", Direction.Output, True)
self.assertTrue(isinstance(prop, classtype))
self.assertEquals("IsOptional", prop.name)
self.assertEquals(Direction.Output, prop.direction)
self.assertTrue(prop.isOptional())
self.assertEquals("test", prop.valueAsStr)

def _do_construction_with_name_default_direction_optional_locking(self, classtype):
prop = classtype("DoesNotLock", "test", Direction.Output, True, False)
self.assertTrue(isinstance(prop, classtype))
self.assertEquals("DoesNotLock", prop.name)
self.assertEquals(Direction.Output, prop.direction)
self.assertTrue(prop.isOptional())
self.assertFalse(prop.isLocking())
self.assertEquals("test", prop.valueAsStr)

def test_WorkspaceProperty_can_be_instantiated(self):
self._do_test(WorkspaceProperty)

def test_MatrixWorkspaceProperty_can_be_instantiated(self):
self._do_test(MatrixWorkspaceProperty)

def test_IEventWorkspaceProperty_can_be_instantiated(self):
self._do_test(IEventWorkspaceProperty)

def test_ITableWorkspaceProperty_can_be_instantiated(self):
self._do_test(ITableWorkspaceProperty)

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

0 comments on commit 8f0376a

Please sign in to comment.