Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a498e24

Browse files
jvansantenstefanseefeld
authored andcommitted
Qualify types defined in other modules
1 parent 7a3cc07 commit a498e24

File tree

4 files changed

+53
-18
lines changed

4 files changed

+53
-18
lines changed

include/boost/python/object/function.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ struct BOOST_PYTHON_DECL function : PyObject
4242

4343
object const& get_namespace() const { return m_namespace; }
4444

45+
object const& get_module() const { return m_module; }
46+
4547
private: // helper functions
4648
object signature(bool show_return_type=false) const;
4749
object signatures(bool show_return_type=false) const;
@@ -53,6 +55,7 @@ struct BOOST_PYTHON_DECL function : PyObject
5355
handle<function> m_overloads;
5456
object m_name;
5557
object m_namespace;
58+
object m_module;
5659
object m_doc;
5760
object m_arg_names;
5861
unsigned m_nkeyword_values;

include/boost/python/object/function_doc_signature.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
namespace boost { namespace python { namespace objects {
1919

2020
class function_doc_signature_generator{
21-
static str py_type_str(const python::detail::signature_element &s);
21+
static str py_type_str(const python::detail::signature_element &s, const object& current_module_name);
2222
static bool arity_cmp( function const *f1, function const *f2 );
2323
static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
2424
static std::vector<function const*> flatten(function const *f);
2525
static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
2626
static str raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
27-
static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
27+
static str parameter_string(py_function const &f, size_t n, object arg_names, const object& module_name, bool cpp_types);
2828
static str pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
2929

3030
public:

src/object/function.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,11 +489,24 @@ void function::add_to_namespace(
489489

490490
assert(!PyErr_Occurred());
491491
handle<> name_space_name(
492-
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
492+
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>(
493+
#if PY_VERSION_HEX < 0x03030000
494+
"__name__"
495+
#else
496+
"__qualname__"
497+
#endif
498+
))));
493499
PyErr_Clear();
494500

495501
if (name_space_name)
496502
new_func->m_namespace = object(name_space_name);
503+
504+
object module_name(
505+
PyObject_IsInstance(name_space.ptr(), upcast<PyObject>(&PyModule_Type))
506+
? object(name_space.attr("__name__"))
507+
: api::getattr(name_space, "__module__", str())
508+
);
509+
new_func->m_module = module_name;
497510
}
498511

499512
if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0)
@@ -670,7 +683,7 @@ extern "C"
670683
static PyObject* function_get_module(PyObject* op, void*)
671684
{
672685
function* f = downcast<function>(op);
673-
object const& ns = f->get_namespace();
686+
object const& ns = f->get_module();
674687
if (!ns.is_none()) {
675688
return python::incref(ns.ptr());
676689
}

src/object/function_doc_signature.cpp

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,47 @@ namespace boost { namespace python { namespace objects {
114114
return res;
115115
}
116116

117-
str function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
117+
static str get_qualname(const PyTypeObject *py_type)
118+
{
119+
# if PY_VERSION_HEX >= 0x03030000
120+
if ( py_type->tp_flags & Py_TPFLAGS_HEAPTYPE )
121+
return str(handle<>(borrowed(((PyHeapTypeObject*)(py_type))->ht_qualname)));
122+
# endif
123+
return str(py_type->tp_name);
124+
}
125+
126+
str function_doc_signature_generator::py_type_str(const python::detail::signature_element &s, const object &current_module_name)
118127
{
119128
if (s.basename==std::string("void")){
120129
static const char * none = "None";
121130
return str(none);
122131
}
123132

124133
PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
125-
#if PY_VERSION_HEX < 0x03030000
126-
if ( py_type )
127-
return str(py_type->tp_name);
128-
#else
129-
if ( py_type && (py_type->tp_flags & Py_TPFLAGS_HEAPTYPE) )
130-
return str(handle<>(borrowed(((PyHeapTypeObject*)(py_type))->ht_qualname)));
131-
#endif
132-
else{
134+
if ( py_type ) {
135+
str name(get_qualname(py_type));
136+
if ( py_type->tp_flags & Py_TPFLAGS_HEAPTYPE ) {
137+
// Qualify the type name if it is defined in a different module.
138+
PyObject *type_module_name = PyDict_GetItemString(py_type->tp_dict, "__module__");
139+
if (
140+
type_module_name
141+
&& PyObject_RichCompareBool(
142+
type_module_name,
143+
current_module_name.ptr(),
144+
Py_NE
145+
) != 0
146+
) {
147+
return str("%s.%s" % make_tuple(handle<>(borrowed(type_module_name)), name));
148+
}
149+
}
150+
return name;
151+
} else {
133152
static const char * object = "object";
134153
return str(object);
135154
}
136155
}
137156

138-
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
157+
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, const object& current_module_name, bool cpp_types)
139158
{
140159
str param;
141160

@@ -161,12 +180,12 @@ namespace boost { namespace python { namespace objects {
161180
{
162181
object kv;
163182
if ( arg_names && (kv = arg_names[n-1]) )
164-
param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
183+
param = str( " (%s)%s" % make_tuple(py_type_str(s[n], current_module_name),kv[0]) );
165184
else
166-
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
185+
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n], current_module_name),"arg", n) );
167186
}
168187
else //we are processing the return type
169-
param = py_type_str(f.get_return_type());
188+
param = py_type_str(f.get_return_type(), current_module_name);
170189
}
171190

172191
//an argument - check for default value and append it
@@ -204,7 +223,7 @@ namespace boost { namespace python { namespace objects {
204223
str param;
205224

206225
formal_params.append(
207-
parameter_string(impl, n, f->m_arg_names, cpp_types)
226+
parameter_string(impl, n, f->m_arg_names, f->get_module(), cpp_types)
208227
);
209228

210229
// find all the arguments with default values preceeding the arity-n_overloads

0 commit comments

Comments
 (0)