Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating python collections.namedtuple from C++ using boost::python

I would like to return a list of collections.namedtuple from a boost::python wrapped function, but I'm not sure how to go about creating these objects from the C++ code. For some other types there is a convenient wrapper (e.g. dict) which makes this easy but nothing like that exists for namedtuple. What is the best way to do this?

Existing code for list of dict:

namespace py = boost::python;

struct cacheWrap {
   ...
   py::list getSources() {
      py::list result;
      for (auto& src : srcCache) {  // srcCache is a C++ vector
         // {{{ --> Want to use a namedtuple here instead of dict
         py::dict pysrc;
         pysrc["url"] = src.url;
         pysrc["label"] = src.label;
         result.append(pysrc);
         // }}}
      }
      return result;
   }
   ...
};


BOOST_PYTHON_MODULE(sole) {
   py::class_<cacheWrap,boost::noncopyable>("doc", py::init<std::string>())
      .def("getSources", &cacheWrap::getSources)
   ;
}
like image 437
ergosys Avatar asked Feb 18 '23 07:02

ergosys


1 Answers

The following code does the job. Better solutions will get the check.

Do this in ctor to set field sourceInfo:

auto collections = py::import("collections");
auto namedtuple = collections.attr("namedtuple");
py::list fields;
fields.append("url"); 
fields.append("label");
sourceInfo = namedtuple("Source", fields);

New method:

py::list getSources() {
   py::list result;
   for (auto& src : srcCache)
      result.append(sourceInfo(src.url, src.label));
   return result;
}
like image 59
ergosys Avatar answered Feb 21 '23 01:02

ergosys