[C++-sig] Boost.python suggestion + pyste bug
Niall Douglas
s_sourceforge at nedprod.com
Fri Aug 8 03:25:05 CEST 2003
It's taken me a few hours, but I've finally found the cause of the
mysterious "AttributeError: can't set attribute" error I kept getting
when I imported my wrapper dll.
If you replace line 29 to 32 in errors.cpp with:
catch(const boost::python::error_already_set&)
{
// The python error reporting has already been handled.
PyErr_SetString(PyExc_RuntimeError, "Boost.python API wrapped more
than once");
}
Then you'll get a much nicer and useful error message. I appreciate
that the comment implies it's already been handled, but I'm
definitely getting "AttributeError: can't set attribute" here which
is really not useful.
Oh Nicodemus! Pyste is generating multiple def()'s with the same name
where it doesn't need them. Here's what's happening: if A inherits B
which inherits C and each of A, B & C provide a method called
"metaClass", then when wrapping A only pyste currently adds a
.def("metaClass", &X::metaClass) where X is A,B,C ie; it adds one for
B & C too where under C++ inheritance rules B::metaClass() and
C::metaClass() disappear. It shouldn't add the B::metaClass() nor
C::metaClass().
A similar problem exists where A, B & C all define a class (let's
call it FXMapEntry). Once again pyste writes out class definitions
for each and every FXMapEntry for each of A, B & C where really it
should only do so for A::FXMapEntry.
And lastly, the other similar problem is for enum's. If A, B & C all
define an enum where C::ID_LAST is B::ID_FIRST and B::ID_LAST is
A::ID_FIRST etc. then pyste defines all the ID_LAST's and ID_FIRST's
(and thus causing a runtime error). It should in this case only
define those items defined in the most derived class.
Speaking of enum's, multiple anonymous enum's (which pyste generates
as _enum<int, "unnamed">) cause boost.python to die because it likes
every enum's first parameter to be a unique type (couldn't we change
this behaviour for simple types?). I worked around this by having
pyste specify a "UniqueInt<n>" where n is a globally incremented
counter. The definition of UniqueInt is:
template<int num> struct UniqueInt { int v; enum { value=num };
UniqueInt(int _v) : v(_v) { } operator int() const { return v; } };
Lastly, am I right in thinking that pyste currently does not use
boost.python's ability to represent C++ class inheritance trees the
same in python classes? I'm thinking that if you were to add support
for this, it kinda works with the fixes necessary for fixing the bugs
above.
Cheers,
Niall
More information about the Cplusplus-sig
mailing list