[C++-sig] rfe: change of behaviour with return_internal_reference policy
gideon may
gideon at computer.org
Mon Aug 19 15:10:37 CEST 2002
Dear Dave,
I have the following code example (obvious stuff missing :
<============================================
class Node {
};
class Leaf1 : public Node {
};
class Leaf2 : public Node {
};
class Group : public Node {
public:
void addChild(Node * child) { _child = child; }
Node * getChild() { return _child; }
private:
Node * _child;
};
toGroup(Node * self) { return dynamic_cast<Group *>(self); }
toLeaf1(Node * self) { return dynamic_cast<Leaf1 *>(self); }
toLeaf2(Node * self) { return dynamic_cast<Leaf2 *>(self); }
BOOST_PYTHON_MODULE_INIT(cast)
{
module("cast")
.add(class_<Node>("Node")
.def_init()
.def("toGroup", &nodeToGroup, return_internal_reference<>())
.def("toLeaf1", &nodeToLeaf1, return_internal_reference<>())
.def("toLeaf2", &nodeToLeaf2, return_internal_reference<>())
)
.add(class_<Group>("Group")
.add(class_<Leaf1>("Leaf1")
.add(class_<Leaf2>("Leaf2")
;
}
=======================================>
this allows me to do stuff like :
>>> g = Group()
>>> n = g.getChild()
>>> l1 = n.toLeaf1()
>>> if l1:
>>> print "I'm leaf1"
>>> l2 = n.toLeaf2()
>>> if l2:
>>> print "I'm leaf2"
Unfortunately it doesn't work, because of the weak references being used
with return_internal_reference.
It seems that within make_nurse_and_patient (life_support.cpp), a weak
reference is being
created between the result and the originator. In my case the result can be
a NULL pointer, failing
the PyWeakref_NewRef function. If however a check is made that the nurse is
an object supporting
weak references the function continues as intended else returning a PyNone,
then
my code works. Thus inserting
if (!PyType_SUPPORTS_WEAKREFS(nurse->ob_type)) {
Py_INCREF(Py_None);
return Py_None;
}
at the beginning of function make_nurse_and_patient would do the trick for
me. Would
this be possible ?
This brings me to a second point, it seems that life_support_dealloc is
never called. If it would,
the tp_free would be called for self, which is not initialized ie a NULL
function pointer.
ciao,
gideon
More information about the Cplusplus-sig
mailing list