set __module__ attribute of functions (fixes #95)

This commit is contained in:
Wenzel Jakob 2016-02-04 23:02:07 +01:00
parent de3ad07899
commit a65017902e
5 changed files with 91 additions and 58 deletions

View File

@ -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

View File

@ -3,6 +3,7 @@ from __future__ import print_function
import sys, pydoc
sys.path.append('.')
import example
from example import Example2
Example2.value = 15
@ -54,3 +55,9 @@ print(instance.pair_passthrough((True, "test")))
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__)

View File

@ -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 0: overwritten
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

View File

@ -36,6 +36,9 @@ template <typename T> arg_t<T> arg::operator=(const T &value) { return arg_t<T>(
/// 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 @@ struct function_record {
/// 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 @@ template <> struct process_attribute<sibling> : process_attribute_default<siblin
/// 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) {

View File

@ -263,10 +263,19 @@ protected:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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;
}