A type pbg knows nothing about?

Asked by nbecker

My function returns to python a type pbg knows nothing about. How do I handle this?

My function will return a boost::numeric::ublas::vector<int>.

Here's what I tried:

-- br.h --
#include <boost/random.hpp>
#include <boost/numeric/ublas/vector.hpp>

typedef boost::mt19937 rng_t;
namespace ublas = boost::numeric::ublas;

struct boost_uniform_int_wrap {
  boost::variate_generator<rng_t&, boost::uniform_int<> > gen;

  boost_uniform_int_wrap (rng_t& r, int min, int max) :
    gen (r, boost::uniform_int<> (min, max)) {}

  int Generate1 () { return gen(); }

  ublas::vector<int> Generate (size_t n) {
    ublas::vector<int> out (n);
    for (ublas::vector<int>::iterator i = out.begin(); i != out.end(); i++)
      *i = Generate1();
    return out;
  }
};
--

== br.py ==
from pybindgen import *
import sys

mod = Module ('br')
mod.add_include ('"br.h"')
rng = mod.add_class('rng_t')
rng.add_constructor([])
rng.add_method ('operator()', ReturnValue.new ('int'), [], custom_name=('__call__'))

u = mod.add_class ('boost_uniform_int_wrap')
u.add_constructor ([param ('rng_t', 'rng'), param ('int', 'min'), param ('int', 'max')])
u.add_method ('Generate1', retval ('int'), [])
u.add_method ('Generate<ublas::vector<int> >', retval ('ublas::vector<int>'), [])
mod.generate (open ('br.cc', 'w'))

  File "<stdin>", line 13, in <module>
  File "/usr/lib/python2.5/site-packages/pybindgen/cppclass.py", line 1080, in add_method
    meth = CppMethod(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/pybindgen/cppmethod.py", line 104, in __init__
    return_value = utils.eval_retval(return_value, self)
  File "/usr/lib/python2.5/site-packages/pybindgen/utils.py", line 218, in eval_retval
    TypeLookupError))
  File "/usr/lib/python2.5/site-packages/pybindgen/utils.py", line 117, in call_with_error_handling
    return callable(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/pybindgen/typehandlers/base.py", line 1058, in new
    return_type_matcher.lookup(ctype)
  File "/usr/lib/python2.5/site-packages/pybindgen/typehandlers/base.py", line 1317, in lookup
    raise TypeLookupError(name)
pybindgen.typehandlers.base.TypeLookupError: ublas::vector< int >

Question information

Language:
English Edit question
Status:
Answered
For:
PyBindGen Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:

This question was reopened

Revision history for this message
nbecker (ndbecker2) said :
#1

Sorry, make that:
u.add_method ('Generate, retval ('ublas::vector<int>'), [])

But, same problem.

The case were 'Generate' is a template is the next test.

Revision history for this message
Gustavo Carneiro (gjc) said :
#2

Sorry, STL containers are not supported yet. Actually I was planning to work on that in the next few days, since I am also needing it, but it's not a trivial thing to support efficiently/generically (recursive types, iterators, ...).

For the time being you can either create your own type handler that converts a std::vector to a python list (complicated if you're not used to it), or manually write the entire wrapper and tell PBG to use it (see CppClass.add_custom_method_wrapper, not difficult if you're used to the plain old Python/C API).

Revision history for this message
nbecker (ndbecker2) said :
#3

Not sure I understood that, I'm not using STL vector here, but boost::numeric::ublas::vector - but I suppose there isn't much difference.

When you say "manually write the entire wrapper", do you have an example?

Revision history for this message
nbecker (ndbecker2) said :
#4

Sorry, I did not mean to choose "problem solved".

Revision history for this message
Gustavo Carneiro (gjc) said :
#5

http://bazaar.launchpad.net/~gjc/pybindgen/trunk/annotate/577?file_id=foomodulegen_common.-20080504152509-y9g9wknpznp7upqq-1

Look for add_custom_* for examples. Of course you have to know/learn Python/C API, but if it's just for one or two methods it shouldn't be too hard.

The only thing special about these wrappers is the additional parameter "PyObject **return_exception", and the "PyErr_Fetch" code in error paths. That is to tie the wrapper into the pybindgen infrastructure that supports overloading, that's all. It's usually just a few copy pasted lines.

Can you help with this problem?

Provide an answer of your own, or ask nbecker for more information if necessary.

To post a message you must log in.