[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 {
    void addChild(Node * child) { _child = child; }
    Node * getChild() { return _child; }
    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); }

            .def("toGroup", &nodeToGroup, return_internal_reference<>())
            .def("toLeaf1", &nodeToLeaf1, return_internal_reference<>())
            .def("toLeaf2", &nodeToLeaf2, return_internal_reference<>())

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, 
my code works. Thus inserting

	if (!PyType_SUPPORTS_WEAKREFS(nurse->ob_type)) {
		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.



More information about the Cplusplus-sig mailing list