|
24 | 24 | #include <algorithm> |
25 | 25 | #include <cstring> |
26 | 26 |
|
| 27 | +#include <stdio.h> |
| 28 | + |
27 | 29 | namespace boost { namespace python { namespace objects { |
28 | 30 |
|
29 | 31 | py_function_impl_base::~py_function_impl_base() |
@@ -177,8 +179,10 @@ void function::argument_error(PyObject* args, PyObject* keywords) const |
177 | 179 | { |
178 | 180 | static handle<> exception( |
179 | 181 | PyErr_NewException("Boost.Python.ArgumentError", PyExc_TypeError, 0)); |
| 182 | + |
| 183 | + object message = "Python argument types in\n %s.%s(" |
| 184 | + % make_tuple(this->m_namespace, this->m_name); |
180 | 185 |
|
181 | | - str message("Python argument types\n ("); |
182 | 186 | list actual; |
183 | 187 | for (int i = 0; i < PyTuple_Size(args); ++i) |
184 | 188 | { |
@@ -214,12 +218,13 @@ void function::argument_error(PyObject* args, PyObject* keywords) const |
214 | 218 | } |
215 | 219 |
|
216 | 220 | signatures.append( |
217 | | - "(%s) -> %s" % make_tuple(str(", ").join(formal), s[0].basename) |
| 221 | + "%s(%s) -> %s" % make_tuple(f->m_name, str(", ").join(formal), s[0].basename) |
218 | 222 | ); |
219 | 223 | } |
220 | 224 |
|
221 | 225 | message += str("\n ").join(signatures); |
222 | 226 |
|
| 227 | + printf("\n--------\n%s\n--------\n", extract<const char*>(message)()); |
223 | 228 | PyErr_SetObject(exception.get(), message.ptr()); |
224 | 229 | throw_error_already_set(); |
225 | 230 | } |
@@ -338,17 +343,19 @@ void function::add_to_namespace( |
338 | 343 | if (dict == 0) |
339 | 344 | throw_error_already_set(); |
340 | 345 |
|
341 | | - // This isn't quite typesafe. We'll shoot first by assuming |
342 | | - // the thing is a function*, then ask questions later. The code works nicer that way. |
343 | | - handle<function> existing( |
344 | | - allow_null(downcast<function>(::PyObject_GetItem(dict, name.ptr()))) |
345 | | - ); |
| 346 | + handle<> existing(allow_null(::PyObject_GetItem(dict, name.ptr()))); |
346 | 347 |
|
347 | 348 | if (existing) |
348 | 349 | { |
349 | 350 | if (existing->ob_type == &function_type) |
350 | 351 | { |
351 | | - new_func->add_overload(existing); |
| 352 | + new_func->add_overload( |
| 353 | + handle<function>( |
| 354 | + borrowed( |
| 355 | + downcast<function>(existing.get()) |
| 356 | + ) |
| 357 | + ) |
| 358 | + ); |
352 | 359 | } |
353 | 360 | else if (existing->ob_type == &PyStaticMethod_Type) |
354 | 361 | { |
@@ -376,9 +383,16 @@ void function::add_to_namespace( |
376 | 383 | // A function is named the first time it is added to a namespace. |
377 | 384 | if (new_func->name().ptr() == Py_None) |
378 | 385 | new_func->m_name = name; |
| 386 | + |
| 387 | + handle<> name_space_name( |
| 388 | + allow_null(::PyObject_GetAttrString(name_space.ptr(), "__name__"))); |
| 389 | + |
| 390 | + if (name_space_name) |
| 391 | + new_func->m_namespace = object(name_space_name); |
379 | 392 | } |
380 | 393 |
|
381 | | - // The PyObject_GetAttrString() call above left an active error |
| 394 | + // The PyObject_GetAttrString() or PyObject_GetItem calls above may |
| 395 | + // have left an active error |
382 | 396 | PyErr_Clear(); |
383 | 397 | if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0) |
384 | 398 | throw_error_already_set(); |
@@ -489,7 +503,9 @@ extern "C" |
489 | 503 |
|
490 | 504 | static PyGetSetDef function_getsetlist[] = { |
491 | 505 | {"__name__", (getter)function_get_name, 0 }, |
| 506 | + {"func_name", (getter)function_get_name, 0 }, |
492 | 507 | {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, |
| 508 | + {"func_doc", (getter)function_get_doc, (setter)function_set_doc}, |
493 | 509 | {NULL} /* Sentinel */ |
494 | 510 | }; |
495 | 511 |
|
|
0 commit comments