make annotations sequenceable from python
authorDiane Trout <diane@caltech.edu>
Thu, 6 Sep 2007 22:44:54 +0000 (22:44 +0000)
committerDiane Trout <diane@caltech.edu>
Thu, 6 Sep 2007 22:44:54 +0000 (22:44 +0000)
e.g. l = [ x for x in mussa.annotations("value")
returns [('name', 'value')

py/annotations.cpp
py/test/TestAnnotations.py

index 4c0c53cca80a34ebd88019a079d8c25be5952b8c..453406dce8105d27e0e1daf55d0160574468fd1a 100644 (file)
@@ -8,11 +8,30 @@
 using namespace boost::python;
 
 #include "alg/annotations.hpp"
 using namespace boost::python;
 
 #include "alg/annotations.hpp"
-
 #include "stl_container_adapter.hpp"
 
 #include "stl_container_adapter.hpp"
 
+#include <stdexcept>
+
+typedef std::pair<std::string const, std::string> pair_string;
+
+struct pair_string_to_tuple 
+{
+  static PyObject * convert(pair_string const &p) {
+    PyObject *key = PyString_FromString(p.first.c_str());
+    PyObject *value = PyString_FromString(p.second.c_str());
+    PyObject *tuple = PyTuple_New(2);
+    if (key == 0 or value == 0 or tuple == 0) 
+      throw std::runtime_error("Allocation Error");
+
+    PyTuple_SetItem(tuple, 0, key);
+    PyTuple_SetItem(tuple, 1, value);
+    return tuple;
+  }
+};
+
 void export_annotations()
 {
 void export_annotations()
 {
+  to_python_converter<pair_string, pair_string_to_tuple>();
 
   class_<Annotations>("annotations", init<std::string>())
     .add_property("name", &Annotations::name, &Annotations::setName)
 
   class_<Annotations>("annotations", init<std::string>())
     .add_property("name", &Annotations::name, &Annotations::setName)
@@ -21,10 +40,12 @@ void export_annotations()
     .def("__getitem__", &map_item<Annotations>::get,
         return_value_policy<copy_non_const_reference>())
     .def("__setitem__", &map_item<Annotations>::set)
     .def("__getitem__", &map_item<Annotations>::get,
         return_value_policy<copy_non_const_reference>())
     .def("__setitem__", &map_item<Annotations>::set)
+    .def("__iter__", iterator<Annotations>())
     .def("__len__", &Annotations::size)
     .def("keys", &map_item<Annotations>::keys)
     .def("values", &map_item<Annotations>::values)
     .def("items", &map_item<Annotations>::items)
     .def("__len__", &Annotations::size)
     .def("keys", &map_item<Annotations>::keys)
     .def("values", &map_item<Annotations>::values)
     .def("items", &map_item<Annotations>::items)
+
     ;
 
   //register_ptr_to_python< AnnotationsRef >();
     ;
 
   //register_ptr_to_python< AnnotationsRef >();
index 32949d47eab01eefdb49abdf9c88a217f91ab4d1..6c432bd98a4a5e1aad25c6fa691abc8d45b0585c 100644 (file)
@@ -19,8 +19,9 @@ class TestAnnotations(unittest.TestCase):
   def testIter(self):
     name_value = 'name_value'
     a = mussa.annotations(name_value)
   def testIter(self):
     name_value = 'name_value'
     a = mussa.annotations(name_value)
-    # It'd be nice if this worked.
-    # l = [ x for x in a ]
+    l = [ x for x in a ]
+    self.failUnlessEqual(len(l), 1)
+    self.failUnlessEqual(l[0], ('name', 'name_value'))
 
 def suite():
   return unittest.makeSuite(TestAnnotations, 'test')
 
 def suite():
   return unittest.makeSuite(TestAnnotations, 'test')