Skip to content

Commit

Permalink
Refs #4399. Better fix for numpy header clash + further namespaces.
Browse files Browse the repository at this point in the history
Also removed a test that can't be made to run consistently on all
platforms.
  • Loading branch information
martyngigg committed Feb 17, 2012
1 parent fa098b3 commit 98e6784
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 367 deletions.
1 change: 0 additions & 1 deletion Code/Mantid/Framework/PythonInterface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ add_subdirectory ( mantid )
set ( TEST_FILES
test/cpp/PythonObjectInstantiatorTest.h
test/cpp/PySequenceToVectorConverterTest.h
# test/cpp/NDArrayToVectorConverterTest.h
)

if ( CXXTEST_FOUND )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,27 @@ namespace Mantid
{
namespace PythonInterface
{

/**
* Converts a Python sequence type to a C++ std::vector, where the vector element
* type is defined by the template type
*/
template <typename DestElementType>
struct DLLExport NDArrayToVectorConverter
namespace Converters
{
/// Constructor
NDArrayToVectorConverter(const boost::python::object & value);
/// Do the conversion
const std::vector<DestElementType> operator()();
private:
/// Check the array is of the correct type and coerce it if not
void typeCheck();
/// Pointer to ndarray object
boost::python::object m_arr;
};

/**
* Converts a Python sequence type to a C++ std::vector, where the vector element
* type is defined by the template type
*/
template <typename DestElementType>
struct DLLExport NDArrayToVectorConverter
{
/// Constructor
NDArrayToVectorConverter(const boost::python::object & value);
/// Do the conversion
const std::vector<DestElementType> operator()();
private:
/// Check the array is of the correct type and coerce it if not
void typeCheck();
/// Pointer to ndarray object
boost::python::object m_arr;
};

}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,12 @@
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
#include "MantidKernel/System.h"
#include <boost/python/detail/prefix.hpp> // Safe include of Python.h

//#define PY_ARRAY_UNIQUE_SYMBOL KERNEL_ARRAY_API
//#define NO_ARRAY_IMPORT
//#include <numpy/ndarrayobject.h>

namespace Mantid
{
namespace PythonInterface
{
namespace Numpy
namespace Converters
{

/**
Expand All @@ -46,33 +41,13 @@ namespace Mantid
* the result of the mapping
*/
template<typename T>
struct NDArrayTypeIndex
{};

/// Macro to define mappings between the CType and Numpy enum
#define DEFINE_TYPE_MAPPING(CType, NDTypeNum) \
template<>\
struct NDArrayTypeIndex<CType>\
{\
static int typenum() { return NDTypeNum; }\
};

DEFINE_TYPE_MAPPING(int16_t, NPY_INT16);
DEFINE_TYPE_MAPPING(uint16_t, NPY_UINT16);
DEFINE_TYPE_MAPPING(int32_t, NPY_INT32);
DEFINE_TYPE_MAPPING(uint32_t, NPY_UINT32);
DEFINE_TYPE_MAPPING(int64_t, NPY_INT64);
#ifdef __APPLE__
DEFINE_TYPE_MAPPING(unsigned long, NPY_ULONG);
#endif
DEFINE_TYPE_MAPPING(uint64_t, NPY_UINT64);
DEFINE_TYPE_MAPPING(double, NPY_DOUBLE);
// Not needed outside here
#undef DEFINE_TYPE_MAPPING
struct DLLExport NDArrayTypeIndex
{
static int typenum;
};

}
}
}


#endif /* MANTID_PYTHONINTERFACE_NDARRAYTYPEINDEX_H_*/
Original file line number Diff line number Diff line change
Expand Up @@ -68,53 +68,56 @@ namespace Mantid

} //end <anonymous>

/**
* Converts a Python sequence type to a C++ std::vector, where the element
* type is defined by the template type
*/
template <typename DestElementType>
struct DLLExport PySequenceToVectorConverter
namespace Converters
{
PySequenceToVectorConverter(const boost::python::object & value)
: m_obj(value.ptr())
{
check(value);
}

/**
* Converts the Python object to a C++ vector
* @return A std::vector<ElementType> containing the values
* from the Python sequence
* Converts a Python sequence type to a C++ std::vector, where the element
* type is defined by the template type
*/
inline const std::vector<DestElementType> operator()()
template <typename DestElementType>
struct DLLExport PySequenceToVectorConverter
{
Py_ssize_t length = PySequence_Size(m_obj);
std::vector<DestElementType> cvector(length);
if(length == 0) return cvector;
ExtractCType<DestElementType> elementConverter;
for( Py_ssize_t i = 0; i < length; ++i )
PySequenceToVectorConverter(const boost::python::object & value)
: m_obj(value.ptr())
{
PyObject *item = PySequence_Fast_GET_ITEM(m_obj, i);
DestElementType element = elementConverter(item);
cvector[i] = element;
check(value);
}
return cvector;
}

private:
inline void check(const boost::python::object & obj)
{
if( !PySequence_Check(obj.ptr()) )
/**
* Converts the Python object to a C++ vector
* @return A std::vector<ElementType> containing the values
* from the Python sequence
*/
inline const std::vector<DestElementType> operator()()
{
throw std::invalid_argument(std::string("PySequenceToVectorConverter expects Python sequence type, found ")
+ obj.ptr()->ob_type->tp_name);
Py_ssize_t length = PySequence_Size(m_obj);
std::vector<DestElementType> cvector(length);
if(length == 0) return cvector;
ExtractCType<DestElementType> elementConverter;
for( Py_ssize_t i = 0; i < length; ++i )
{
PyObject *item = PySequence_Fast_GET_ITEM(m_obj, i);
DestElementType element = elementConverter(item);
cvector[i] = element;
}
return cvector;
}
}
/// Python object to convert
PyObject *m_obj;

};
private:
inline void check(const boost::python::object & obj)
{
if( !PySequence_Check(obj.ptr()) )
{
throw std::invalid_argument(std::string("PySequenceToVectorConverter expects Python sequence type, found ")
+ obj.ptr()->ob_type->tp_name);
}
}
/// Python object to convert
PyObject *m_obj;

};

}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Mantid
{

///@cond
namespace detail
namespace
{
/**
* Converts a T object to a Python object and performs an upcast if it can.
Expand All @@ -72,28 +72,31 @@ namespace Mantid

};

} // namespace detail
} // end <anonymous>
///@endcond

/**
* Implements the upcast_shared_ptr return_value_policy.
* This defines the required an internal type apply::type
* used by the return_value_policy mechanism
*/
struct upcast_returned_value
namespace Policies
{
template <class T>
struct apply
/**
* Implements the upcast_shared_ptr return_value_policy.
* This defines the required an internal type apply::type
* used by the return_value_policy mechanism
*/
struct upcast_returned_value
{
typedef typename boost::mpl::if_c<
boost::mpl::or_<boost::is_convertible<T, boost::shared_ptr<Kernel::DataItem> >,
boost::is_convertible<T, boost::weak_ptr<Kernel::DataItem> > >::value
, detail::to_python_value_with_upcast<T>
, boost::python::to_python_value<T>
>::type type;
template <class T>
struct apply
{
typedef typename boost::mpl::if_c<
boost::mpl::or_<boost::is_convertible<T, boost::shared_ptr<Kernel::DataItem> >,
boost::is_convertible<T, boost::weak_ptr<Kernel::DataItem> > >::value
, to_python_value_with_upcast<T>
, boost::python::to_python_value<T>
>::type type;
};
};
};

} // Policies
}
} // namespace Mantid::PythonInterface

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
boost::python::bases<Mantid::Kernel::Property>, boost::noncopyable>("PropertyWithValue_"#suffix, boost::python::no_init) \
.add_property("value", \
make_function(&Mantid::Kernel::PropertyWithValue<type>::operator(),\
boost::python::return_value_policy<Mantid::PythonInterface::upcast_returned_value>())) \
boost::python::return_value_policy<Mantid::PythonInterface::Policies::upcast_returned_value>())) \
;

#endif /* MANTID_PYTHONINTERFACE_PROPERTY_HPP_ */
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ using Mantid::API::AnalysisDataServiceImpl;
using Mantid::API::AnalysisDataService;
using Mantid::Kernel::DataItem;
using Mantid::Kernel::DataItem_sptr;
namespace Policies = Mantid::PythonInterface::Policies;
using namespace boost::python;


/// Weak pointer to DataItem typedef
typedef boost::weak_ptr<DataItem> DataItem_wptr;

Expand Down Expand Up @@ -76,15 +78,15 @@ void export_AnalysisDataService()
.def("Instance", &AnalysisDataService::Instance, return_value_policy<reference_existing_object>(),
"Return a reference to the ADS singleton")
.staticmethod("Instance")
.def("retrieve", &retrieveAsWeakPtr, return_value_policy<Mantid::PythonInterface::upcast_returned_value>(),
.def("retrieve", &retrieveAsWeakPtr, return_value_policy<Policies::upcast_returned_value>(),
"Retrieve the named object. Raises an exception if the name does not exist")
.def("remove", &AnalysisDataServiceImpl::remove, "Remove a named object")
.def("clear", &AnalysisDataServiceImpl::clear, "Removes all objects managed by the service.")
.def("size", &AnalysisDataServiceImpl::size, "Returns the number of objects within the service")
.def("getObjectNames", &getObjectNamesAsList, "Return the list of names currently known to the ADS")
// Make it act like a dictionary
.def("__len__", &AnalysisDataServiceImpl::size)
.def("__getitem__", &retrieveAsWeakPtr, return_value_policy<Mantid::PythonInterface::upcast_returned_value>())
.def("__getitem__", &retrieveAsWeakPtr, return_value_policy<Policies::upcast_returned_value>())
.def("__contains__", &AnalysisDataServiceImpl::doesExist)
.def("__delitem__", &AnalysisDataServiceImpl::remove)
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL
#define PY_ARRAY_UNIQUE_SYMBOL API_ARRAY_API
#define NO_IMPORT_ARRAY
#include <numpy/ndarrayobject.h>
#include <numpy/arrayobject.h>


using Mantid::API::Axis;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ using Mantid::API::WorkspaceGroup;
using Mantid::API::WorkspaceGroup_sptr;
using Mantid::API::Workspace;
using Mantid::API::Workspace_sptr;

namespace Policies = Mantid::PythonInterface::Policies;
using namespace boost::python;

namespace
Expand All @@ -38,12 +38,12 @@ void export_WorkspaceGroup()
.def("add", &WorkspaceGroup::add, "Add a name to the group")
.def("size", &WorkspaceGroup::size, "Returns the number of workspaces contained in the group")
.def("remove", &WorkspaceGroup::remove, "Remove a name from the group")
.def("getItem", &getItemAsWeakPtr, return_value_policy<Mantid::PythonInterface::upcast_returned_value>(),
.def("getItem", &getItemAsWeakPtr, return_value_policy<Policies::upcast_returned_value>(),
"Returns the item at the given index")
// ------------ Operators --------------------------------
.def("__len__", &WorkspaceGroup::getNumberOfEntries)
.def("__contains__", &WorkspaceGroup::contains)
.def("__getitem__",&getItemAsWeakPtr, return_value_policy<Mantid::PythonInterface::upcast_returned_value>())
.def("__getitem__",&getItemAsWeakPtr, return_value_policy<Policies::upcast_returned_value>())
;

REGISTER_SINGLEVALUE_HANDLER(WorkspaceGroup_sptr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// See http://docs.scipy.org/doc/numpy/reference/c-api.array.html#PY_ARRAY_UNIQUE_SYMBOL
#define PY_ARRAY_UNIQUE_SYMBOL API_ARRAY_API
#define NO_IMPORT_ARRAY
#include <numpy/ndarrayobject.h>
#include <numpy/arrayobject.h>

namespace Mantid
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ set ( EXPORT_FILES

set ( SRC_FILES
src/Converters/NDArrayToVectorConverter.cpp
src/Converters/NDArrayTypeIndex.cpp
src/Registry/SequenceTypeHandler.cpp
src/Registry/TypeRegistry.cpp
src/Registry/UpcastRegistry.cpp
Expand Down

0 comments on commit 98e6784

Please sign in to comment.