2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-19 04:22:16 +00:00

Qualify types defined in other modules

This commit is contained in:
Jakob van Santen
2023-04-25 15:46:28 +02:00
committed by Stefan Seefeld
parent 7a3cc07042
commit a498e2458c
4 changed files with 53 additions and 18 deletions

View File

@@ -42,6 +42,8 @@ struct BOOST_PYTHON_DECL function : PyObject
object const& get_namespace() const { return m_namespace; }
object const& get_module() const { return m_module; }
private: // helper functions
object signature(bool show_return_type=false) const;
object signatures(bool show_return_type=false) const;
@@ -53,6 +55,7 @@ struct BOOST_PYTHON_DECL function : PyObject
handle<function> m_overloads;
object m_name;
object m_namespace;
object m_module;
object m_doc;
object m_arg_names;
unsigned m_nkeyword_values;

View File

@@ -18,13 +18,13 @@
namespace boost { namespace python { namespace objects {
class function_doc_signature_generator{
static str py_type_str(const python::detail::signature_element &s);
static str py_type_str(const python::detail::signature_element &s, const object& current_module_name);
static bool arity_cmp( function const *f1, function const *f2 );
static bool are_seq_overloads( function const *f1, function const *f2 , bool check_docs);
static std::vector<function const*> flatten(function const *f);
static std::vector<function const*> split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change);
static str raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
static str parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types);
static str parameter_string(py_function const &f, size_t n, object arg_names, const object& module_name, bool cpp_types);
static str pretty_signature(function const *f, size_t n_overloads, bool cpp_types = false);
public:

View File

@@ -489,11 +489,24 @@ void function::add_to_namespace(
assert(!PyErr_Occurred());
handle<> name_space_name(
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>(
#if PY_VERSION_HEX < 0x03030000
"__name__"
#else
"__qualname__"
#endif
))));
PyErr_Clear();
if (name_space_name)
new_func->m_namespace = object(name_space_name);
object module_name(
PyObject_IsInstance(name_space.ptr(), upcast<PyObject>(&PyModule_Type))
? object(name_space.attr("__name__"))
: api::getattr(name_space, "__module__", str())
);
new_func->m_module = module_name;
}
if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0)
@@ -670,7 +683,7 @@ extern "C"
static PyObject* function_get_module(PyObject* op, void*)
{
function* f = downcast<function>(op);
object const& ns = f->get_namespace();
object const& ns = f->get_module();
if (!ns.is_none()) {
return python::incref(ns.ptr());
}

View File

@@ -114,7 +114,16 @@ namespace boost { namespace python { namespace objects {
return res;
}
str function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
static str get_qualname(const PyTypeObject *py_type)
{
# if PY_VERSION_HEX >= 0x03030000
if ( py_type->tp_flags & Py_TPFLAGS_HEAPTYPE )
return str(handle<>(borrowed(((PyHeapTypeObject*)(py_type))->ht_qualname)));
# endif
return str(py_type->tp_name);
}
str function_doc_signature_generator::py_type_str(const python::detail::signature_element &s, const object &current_module_name)
{
if (s.basename==std::string("void")){
static const char * none = "None";
@@ -122,20 +131,30 @@ namespace boost { namespace python { namespace objects {
}
PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
#if PY_VERSION_HEX < 0x03030000
if ( py_type )
return str(py_type->tp_name);
#else
if ( py_type && (py_type->tp_flags & Py_TPFLAGS_HEAPTYPE) )
return str(handle<>(borrowed(((PyHeapTypeObject*)(py_type))->ht_qualname)));
#endif
else{
if ( py_type ) {
str name(get_qualname(py_type));
if ( py_type->tp_flags & Py_TPFLAGS_HEAPTYPE ) {
// Qualify the type name if it is defined in a different module.
PyObject *type_module_name = PyDict_GetItemString(py_type->tp_dict, "__module__");
if (
type_module_name
&& PyObject_RichCompareBool(
type_module_name,
current_module_name.ptr(),
Py_NE
) != 0
) {
return str("%s.%s" % make_tuple(handle<>(borrowed(type_module_name)), name));
}
}
return name;
} else {
static const char * object = "object";
return str(object);
}
}
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
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)
{
str param;
@@ -161,12 +180,12 @@ namespace boost { namespace python { namespace objects {
{
object kv;
if ( arg_names && (kv = arg_names[n-1]) )
param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
param = str( " (%s)%s" % make_tuple(py_type_str(s[n], current_module_name),kv[0]) );
else
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n], current_module_name),"arg", n) );
}
else //we are processing the return type
param = py_type_str(f.get_return_type());
param = py_type_str(f.get_return_type(), current_module_name);
}
//an argument - check for default value and append it
@@ -204,7 +223,7 @@ namespace boost { namespace python { namespace objects {
str param;
formal_params.append(
parameter_string(impl, n, f->m_arg_names, cpp_types)
parameter_string(impl, n, f->m_arg_names, f->get_module(), cpp_types)
);
// find all the arguments with default values preceeding the arity-n_overloads