Skip to content

Commit f7a5e6d

Browse files
committed
Moved add_overload functionality to function::add_to_namespace
[SVN r12385]
1 parent dabb22b commit f7a5e6d

File tree

2 files changed

+44
-21
lines changed

2 files changed

+44
-21
lines changed

src/module.cpp

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// producing this work.
88

99
#include <boost/python/module.hpp>
10-
#include <boost/python/errors.hpp>
1110

1211
namespace boost { namespace python {
1312

@@ -47,32 +46,16 @@ void module_base::add(PyObject* x, const char* name)
4746

4847
void module_base::add(ref x, const char* name)
4948
{
50-
ref f(x); // First take possession of the object.
51-
if (PyObject_SetAttrString(m_module, const_cast<char*>(name), x.get()) < 0)
52-
throw error_already_set();
49+
// Use function::add_to_namespace to achieve overloading if
50+
// appropriate.
51+
objects::function::add_to_namespace(m_module, name, x.get());
5352
}
5453

5554
void module_base::add(PyTypeObject* x, const char* name /*= 0*/)
5655
{
5756
this->add((PyObject*)x, name ? name : x->tp_name);
5857
}
5958

60-
void module_base::add_overload(objects::function* x, const char* name)
61-
{
62-
PyObject* existing = PyObject_HasAttrString(m_module, const_cast<char*>(name))
63-
? PyObject_GetAttrString(m_module, const_cast<char*>(name))
64-
: 0;
65-
66-
if (existing != 0 && existing->ob_type == &objects::function_type)
67-
{
68-
static_cast<objects::function*>(existing)->add_overload(x);
69-
}
70-
else
71-
{
72-
add(x, name);
73-
}
74-
}
75-
7659
PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } };
7760

7861
}} // namespace boost::python

src/object/function.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
#include <boost/python/object/function.hpp>
88
#include <numeric>
9+
#include <boost/python/errors.hpp>
10+
#include <boost/python/objects.hpp>
911

1012
namespace boost { namespace python { namespace objects {
1113

@@ -28,7 +30,7 @@ function::~function()
2830

2931
PyObject* 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

6466
void 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+
75115
extern "C"
76116
{
77117
// Stolen from Python's funcobject.c

0 commit comments

Comments
 (0)