66
77#include < boost/python/object/function.hpp>
88#include < numeric>
9+ #include < boost/python/errors.hpp>
10+ #include < boost/python/objects.hpp>
911
1012namespace boost { namespace python { namespace objects {
1113
@@ -28,7 +30,7 @@ function::~function()
2830
2931PyObject* function::call (PyObject* args, PyObject* keywords) const
3032{
31- int nargs = PyTuple_GET_SIZE (args);
33+ std:: size_t nargs = PyTuple_GET_SIZE (args);
3234 function const * f = this ;
3335 do
3436 {
@@ -63,6 +65,8 @@ void function::argument_error(PyObject* args, PyObject* keywords) const
6365
6466void function::add_overload (function* overload)
6567{
68+ Py_XINCREF (overload);
69+
6670 function* parent = this ;
6771
6872 while (parent->m_overloads != 0 )
@@ -72,6 +76,42 @@ void function::add_overload(function* overload)
7276 parent->m_overloads = overload;
7377}
7478
79+ void function::add_to_namespace (
80+ PyObject* name_space, char const * name_, PyObject* attribute_)
81+ {
82+ ref attribute (attribute_, ref::increment_count);
83+ string name (name_);
84+
85+ if (attribute_->ob_type == &function_type)
86+ {
87+ PyObject* dict = 0 ;
88+
89+ if (PyClass_Check (name_space))
90+ dict = ((PyClassObject*)name_space)->cl_dict ;
91+ else if (PyType_Check (name_space))
92+ dict = ((PyTypeObject*)name_space)->tp_dict ;
93+ else
94+ dict = PyObject_GetAttrString (name_space, " __dict__" );
95+
96+ if (dict == 0 )
97+ throw error_already_set ();
98+
99+ ref existing (PyObject_GetItem (dict, name.get ()), ref::null_ok);
100+
101+ if (existing.get () && existing->ob_type == &function_type)
102+ {
103+ static_cast <function*>(existing.get ())->add_overload (
104+ static_cast <function*>(attribute_));
105+ return ;
106+ }
107+ }
108+
109+ // The PyObject_GetAttrString() call above left an active error
110+ PyErr_Clear ();
111+ if (PyObject_SetAttr (name_space, name.get (), attribute_) < 0 )
112+ throw error_already_set ();
113+ }
114+
75115extern " C"
76116{
77117 // Stolen from Python's funcobject.c
0 commit comments