Здравствуйте.
Возникла проблема, которую удалось локализовать и составить минимальную программу, воспроизводящую её. К сожалению, я не настолько хорошо знаю внутренне устройство boost::python, чтобы самостоятельно разобраться с выявленной ошибкой.
tree.h:
#ifndef _TREE_H_
#define _TREE_H_
#include <boost/smart_ptr.hpp>
#include <map>
class TreeNode;
typedef boost::shared_ptr<TreeNode> TreeNodePtr;
struct EdgeProperties {
    std::size_t weight;
    EdgeProperties();
    EdgeProperties(const std::size_t weight_);
};
typedef std::map<TreeNodePtr, EdgeProperties> EdgesMap;
class TreeNode {
    public:
        typedef std::map<TreeNodePtr, EdgeProperties> ChildNodes;
        const EdgeProperties& edgeProperties(const TreeNodePtr& node) const;
        const EdgesMap& childNodes() const;
        void addChild(const TreeNodePtr& node, const EdgeProperties& properties);
    private:
        EdgesMap children;
};
#endif
tree.cpp:
#include "tree.h"
#include <stdexcept>
EdgeProperties::EdgeProperties():
    weight()
{}
EdgeProperties::EdgeProperties(const std::size_t weight_):
    weight(weight_)
{}
const EdgeProperties& TreeNode::edgeProperties(const TreeNodePtr& node) const {
    EdgesMap::const_iterator pos(children.find(node));
    if (pos == children.end())
        throw std::runtime_error("Not in tree.");
    return pos->second;
}
const EdgesMap& TreeNode::childNodes() const {
    return children;
}
void TreeNode::addChild(const TreeNodePtr& node, const EdgeProperties& properties) {
    children[node] = properties;
}
trees_module.cpp:
#include <boost/python.hpp>
#include "tree.h"
using namespace boost::python;
template <class C>
inline boost::python::dict toDict(const C& v) {
    boost::python::dict d;
    for (typename C::const_iterator i = v.begin(); i != v.end(); ++i)
        d[i->first] = i->second;
    return d;
}
dict getChildNodes(const TreeNode& t) {
    return toDict(t.childNodes());
}
BOOST_PYTHON_MODULE(trees) {
    class_<EdgeProperties>("EdgeProperties", init<>())
        .def(init<const std::size_t>())
        .add_property("weight", &EdgeProperties::weight, &EdgeProperties::weight)
    ;
    class_<TreeNode, TreeNodePtr, boost::noncopyable>("TreeNode", init<>())
        .def("edgeProperties", &TreeNode::edgeProperties, return_internal_reference<>())
        .def("childNodes", &getChildNodes)
        .def("addChild", &TreeNode::addChild)
    ;
}
test.cpp:
#include "tree.h"
#include <iostream>
#include <iomanip>
int main(int, char**) {
    TreeNodePtr n0(new TreeNode());
    TreeNodePtr n1(new TreeNode());
    n0->addChild(n1, EdgeProperties(2));
    const EdgesMap& edges(n0->childNodes());
    std::cout
        << std::boolalpha << (edges.find(n1) != edges.end()) << std::endl
        << n0->edgeProperties(n1).weight << std::endl;
    return 0;
}
test.py:
from trees import *
n0 = TreeNode()
n1 = TreeNode()
n0.addChild(n1, EdgeProperties(2))
print n1 in n0.childNodes()
print n0.edgeProperties(n1).weight
Сборка и запуск:
$ g++ tree.cpp test.cpp -o test
$ g++ -shared -fPIC -lboost_python -lpython2.5 -I /usr/include/python2.5 tree.cpp trees_module.cpp -o trees.so
$ ./test
true
2
$ python test.py
True
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    print n0.edgeProperties(n1)
RuntimeError: Not in tree.
$
Итак, вопрос: почему при вызове edgeProperties из python получается так, что n1 отсутствует в списке дочерних узлов n0, хотя строчкой ранее успешно проверяется, что он там есть? В то же время тест на с++ проходит успешно. Где ошибка?