diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index e44ca5b2..f29d3448 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -39,6 +39,8 @@ struct BOOST_PYTHON_DECL function : PyObject void doc(object const& x); object const& name() const; + + object const& get_namespace() const { return m_namespace; } private: // helper functions object signature(bool show_return_type=false) const; diff --git a/src/object/function.cpp b/src/object/function.cpp index 98c7c966..9328e014 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -670,11 +670,26 @@ extern "C" { return python::incref(upcast(&PyCFunction_Type)); } + + static PyObject* function_get_module(PyObject* op, void*) + { + function* f = downcast(op); + object const& ns = f->get_namespace(); + if (!ns.is_none()) { + return python::incref(ns.ptr()); + } + PyErr_SetString( + PyExc_AttributeError, const_cast( + "Boost.Python function __module__ unknown.")); + return 0; + } } static PyGetSetDef function_getsetlist[] = { {const_cast("__name__"), (getter)function_get_name, 0, 0, 0 }, {const_cast("func_name"), (getter)function_get_name, 0, 0, 0 }, + {const_cast("__module__"), (getter)function_get_module, 0, 0, 0 }, + {const_cast("func_module"), (getter)function_get_module, 0, 0, 0 }, {const_cast("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above {const_cast("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0}, {const_cast("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0}, diff --git a/test/pytype_function.py b/test/pytype_function.py index 7927629b..83674632 100755 --- a/test/pytype_function.py +++ b/test/pytype_function.py @@ -7,6 +7,11 @@ >>> print func.__doc__.splitlines()[1] func( (A)arg1) -> A : +>>> print func.__module__ +pytype_function_ext + +>>> print func.__name__ +func """ def run(args = None): import sys