set __module__ attribute of functions (fixes #95)
diff --git a/example/example11.ref b/example/example11.ref
index 7d75056..8edc065 100644
--- a/example/example11.ref
+++ b/example/example11.ref
@@ -1,19 +1,19 @@
-Help on built-in function kw_func
+Help on built-in function kw_func in module example
kkww__ffuunncc(...)
Signature : (x : int, y : int) -> NoneType
-Help on built-in function kw_func2
+Help on built-in function kw_func2 in module example
kkww__ffuunncc22(...)
Signature : (x : int = 100L, y : int = 200L) -> NoneType
-Help on built-in function kw_func3
+Help on built-in function kw_func3 in module example
kkww__ffuunncc33(...)
Signature : (data : unicode = u'Hello world!') -> NoneType
-Help on built-in function kw_func4
+Help on built-in function kw_func4 in module example
kkww__ffuunncc44(...)
Signature : (myList : list<int> = [13L, 17L]) -> NoneType
diff --git a/example/example2.py b/example/example2.py
index 4220134..f8bda4d 100755
--- a/example/example2.py
+++ b/example/example2.py
@@ -3,6 +3,7 @@
import sys, pydoc
sys.path.append('.')
+import example
from example import Example2
Example2.value = 15
@@ -54,3 +55,9 @@
print(instance.tuple_passthrough((True, "test", 5)))
print(pydoc.render_doc(Example2, "Help on %s"))
+
+print("__name__(example) = %s" % example.__name__)
+print("__name__(example.Example2) = %s" % Example2.__name__)
+print("__module__(example.Example2) = %s" % Example2.__module__)
+print("__name__(example.Example2.get_set) = %s" % Example2.get_set.__name__)
+print("__module__(example.Example2.get_set) = %s" % Example2.get_set.__module__)
diff --git a/example/example2.ref b/example/example2.ref
index a63c3cd..08fb7cc 100644
--- a/example/example2.ref
+++ b/example/example2.ref
@@ -1,11 +1,15 @@
-key: key, value=value
+15
+5
+example.Example2: No constructor defined!
+can't set attribute
key: key2, value=value2
key: key, value=value
+key: key, value=value
key: key2, value=value2
key: key3
-key: key1
key: key2
key: key1
+key: key1
key: key2
key: key3
Entry at positon 0: value
@@ -13,107 +17,108 @@
list item 1: value2
list item 0: value
list item 1: value2
-15
-5
-example.Example2: No constructor defined!
-can't set attribute
This exception was intentionally thrown.
-('test', True)
-(5, 'test', True)
+(u'test', True)
+(5L, u'test', True)
Help on class Example2 in module example
-class EExxaammppllee22(builtins.object)
+class EExxaammppllee22(__builtin__.object)
| Example 2 documentation
|
| Methods defined here:
|
- | ____iinniitt____(self, /, *args, **kwargs)
- | Initialize self. See help(type(self)) for accurate signature.
+ | ____iinniitt____(...)
+ | x.__init__(...) initializes x; see help(type(x)) for signature
|
- | ____nneeww____ = <built-in method __new__ of example.Example2_meta object>
- | ggeett__ddiicctt(...) from builtins.PyCapsule
+ | ggeett__ddiicctt(...)
| Signature : (example.Example2) -> dict
|
| Return a Python dictionary
|
- | ggeett__ddiicctt__22(...) from builtins.PyCapsule
- | Signature : (example.Example2) -> dict<str, str>
+ | ggeett__ddiicctt__22(...)
+ | Signature : (example.Example2) -> dict<unicode, unicode>
|
| Return a C++ dictionary
|
- | ggeett__lliisstt(...) from builtins.PyCapsule
+ | ggeett__lliisstt(...)
| Signature : (example.Example2) -> list
|
| Return a Python list
|
- | ggeett__lliisstt__22(...) from builtins.PyCapsule
- | Signature : (example.Example2) -> list<str>
+ | ggeett__lliisstt__22(...)
+ | Signature : (example.Example2) -> list<unicode>
|
| Return a C++ list
|
- | ggeett__sseett(...) from builtins.PyCapsule
+ | ggeett__sseett(...)
| Signature : (example.Example2) -> set
|
| Return a Python set
|
- | ggeett__sseett22(...) from builtins.PyCapsule
+ | ggeett__sseett22(...)
| Signature : (example.Example2) -> set
|
| Return a C++ set
|
- | nneeww__iinnssttaannccee(...) from builtins.PyCapsule
- | Signature : () -> example.Example2
- |
- | Return an instance
- |
- | ppaaiirr__ppaasssstthhrroouugghh(...) from builtins.PyCapsule
- | Signature : (example.Example2, (bool, str)) -> (str, bool)
+ | ppaaiirr__ppaasssstthhrroouugghh(...)
+ | Signature : (example.Example2, (bool, unicode)) -> (unicode, bool)
|
| Return a pair in reversed order
|
- | pprriinntt__ddiicctt(...) from builtins.PyCapsule
- | Signature : (example.Example2, dict) -> None
+ | pprriinntt__ddiicctt(...)
+ | Signature : (example.Example2, dict) -> NoneType
|
| Print entries of a Python dictionary
|
- | pprriinntt__ddiicctt__22(...) from builtins.PyCapsule
- | Signature : (example.Example2, dict<str, str>) -> None
+ | pprriinntt__ddiicctt__22(...)
+ | Signature : (example.Example2, dict<unicode, unicode>) -> NoneType
|
| Print entries of a C++ dictionary
|
- | pprriinntt__lliisstt(...) from builtins.PyCapsule
- | Signature : (example.Example2, list) -> None
+ | pprriinntt__lliisstt(...)
+ | Signature : (example.Example2, list) -> NoneType
|
| Print entries of a Python list
|
- | pprriinntt__lliisstt__22(...) from builtins.PyCapsule
- | Signature : (example.Example2, list<str>) -> None
+ | pprriinntt__lliisstt__22(...)
+ | Signature : (example.Example2, list<unicode>) -> NoneType
|
| Print entries of a C++ list
|
- | pprriinntt__sseett(...) from builtins.PyCapsule
- | Signature : (example.Example2, set) -> None
+ | pprriinntt__sseett(...)
+ | Signature : (example.Example2, set) -> NoneType
|
| Print entries of a Python set
|
- | pprriinntt__sseett__22(...) from builtins.PyCapsule
- | Signature : (example.Example2, set<str>) -> None
+ | pprriinntt__sseett__22(...)
+ | Signature : (example.Example2, set<unicode>) -> NoneType
|
| Print entries of a C++ set
|
- | tthhrrooww__eexxcceeppttiioonn(...) from builtins.PyCapsule
- | Signature : (example.Example2) -> None
+ | tthhrrooww__eexxcceeppttiioonn(...)
+ | Signature : (example.Example2) -> NoneType
|
| Throw an exception
|
- | ttuuppllee__ppaasssstthhrroouugghh(...) from builtins.PyCapsule
- | Signature : (example.Example2, (bool, str, int)) -> (int, str, bool)
+ | ttuuppllee__ppaasssstthhrroouugghh(...)
+ | Signature : (example.Example2, (bool, unicode, int)) -> (int, unicode, bool)
|
| Return a triple in reversed order
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
- | ____ppyybbiinndd1111____ = <capsule object NULL>
+ | ____nneeww____ = <built-in method __new__ of example.Example2__Meta object>
+ | T.__new__(S, ...) -> a new object with type S, a subtype of T
+ |
+ | nneeww__iinnssttaannccee = <built-in method new_instance of PyCapsule object>
+ | Signature : () -> example.Example2
+ |
+ | Return an instance
+__name__(example) = example
+__name__(example.Example2) = Example2
+__module__(example.Example2) = example
+__name__(example.Example2.get_set) = get_set
+__module__(example.Example2.get_set) = example
Destructing Example2
diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h
index 6eb8ac8..92fceeb 100644
--- a/include/pybind11/attr.h
+++ b/include/pybind11/attr.h
@@ -36,6 +36,9 @@
/// Annotation for methods
struct is_method { handle class_; is_method(const handle &c) : class_(c) { } };
+/// Annotation for parent scope
+struct scope { handle value; scope(const handle &s) : value(s) { } };
+
/// Annotation for documentation
struct doc { const char *value; doc(const char *value) : value(value) { } };
@@ -105,6 +108,9 @@
/// Python handle to the associated class (if this is method)
handle class_;
+ /// Python handle to the parent scope (a class or a module)
+ handle scope;
+
/// Python handle to the sibling function representing an overload chain
handle sibling;
@@ -190,9 +196,15 @@
/// Process an attribute which indicates that this function is a method
template <> struct process_attribute<is_method> : process_attribute_default<is_method> {
- static void init(const is_method &s, function_record *r) { r->class_ = s.class_; }
+ static void init(const is_method &s, function_record *r) { r->class_ = s.class_; r->scope = s.class_; }
};
+/// Process an attribute which indicates the parent scope of a method
+template <> struct process_attribute<scope> : process_attribute_default<scope> {
+ static void init(const scope &s, function_record *r) { r->scope = s.value; }
+};
+
+
/// Process a keyword argument attribute (*without* a default value)
template <> struct process_attribute<arg> : process_attribute_default<arg> {
static void init(const arg &a, function_record *r) {
diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h
index b6de431..02b3b7c 100644
--- a/include/pybind11/pybind11.h
+++ b/include/pybind11/pybind11.h
@@ -263,10 +263,19 @@
rec->def->ml_name = rec->name;
rec->def->ml_meth = reinterpret_cast<PyCFunction>(*dispatcher);
rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;
+
capsule rec_capsule(rec, [](PyObject *o) {
destruct((detail::function_record *) PyCapsule_GetPointer(o, nullptr));
});
- m_ptr = PyCFunction_New(rec->def, rec_capsule.ptr());
+
+ object scope_module;
+ if (rec->scope) {
+ scope_module = (object) rec->scope.attr("__module__");
+ if (!scope_module)
+ scope_module = (object) rec->scope.attr("__name__");
+ }
+
+ m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr());
if (!m_ptr)
pybind11_fail("cpp_function::cpp_function(): Could not allocate function object");
} else {
@@ -467,7 +476,7 @@
template <typename Func, typename... Extra>
module &def(const char *name_, Func &&f, const Extra& ... extra) {
cpp_function func(std::forward<Func>(f), name(name_),
- sibling((handle) attr(name_)), extra...);
+ sibling((handle) attr(name_)), scope(*this), extra...);
/* PyModule_AddObject steals a reference to 'func' */
PyModule_AddObject(ptr(), name_, func.inc_ref().ptr());
return *this;
@@ -742,26 +751,26 @@
template <typename Func, typename... Extra> class_ &
def_static(const char *name_, Func f, const Extra&... extra) {
cpp_function cf(std::forward<Func>(f), name(name_),
- sibling(attr(name_)), extra...);
+ sibling(attr(name_)), scope(*this), extra...);
attr(cf.name()) = cf;
return *this;
}
template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra>
class_ &def(const detail::op_<id, ot, L, R> &op, const Extra&... extra) {
- op.template execute<type>(*this, extra...);
+ op.template execute<type>(*this, is_method(*this), extra...);
return *this;
}
template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra>
class_ & def_cast(const detail::op_<id, ot, L, R> &op, const Extra&... extra) {
- op.template execute_cast<type>(*this, extra...);
+ op.template execute_cast<type>(*this, is_method(*this), extra...);
return *this;
}
template <typename... Args, typename... Extra>
class_ &def(const detail::init<Args...> &init, const Extra&... extra) {
- init.template execute<type>(*this, extra...);
+ init.template execute<type>(*this, is_method(*this), extra...);
return *this;
}
@@ -800,8 +809,8 @@
template <typename D, typename... Extra>
class_ &def_readwrite_static(const char *name, D *pm, const Extra& ...extra) {
cpp_function fget([pm](object) -> const D &{ return *pm; },
- return_value_policy::reference_internal, extra...),
- fset([pm](object, const D &value) { *pm = value; }, extra...);
+ return_value_policy::reference_internal, scope(*this), extra...),
+ fset([pm](object, const D &value) { *pm = value; }, scope(*this), extra...);
def_property_static(name, fget, fset);
return *this;
}
@@ -809,7 +818,7 @@
template <typename D, typename... Extra>
class_ &def_readonly_static(const char *name, const D *pm, const Extra& ...extra) {
cpp_function fget([pm](object) -> const D &{ return *pm; },
- return_value_policy::reference_internal, extra...);
+ return_value_policy::reference_internal, scope(*this), extra...);
def_property_readonly_static(name, fget);
return *this;
}