From bee4cd31d60f3b35a37a2eb98fdfc60ba76cfe1c Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Tue, 26 Oct 2021 17:38:46 +0200 Subject: __feature__: handle properties with function overloads This is the implementation, see the conclusion of the issue. [ChangeLog][PySide6] When a property would override an existing function with multiple arity or parameters, append an underscore to the property name. REMARK: The current implementation is very correct. It uses introspection via the signature module. But that adds a constant overhead to the true_property feature. Actually, there are only 2 known cases where this overlap happens. It might be considered to simplify things by checking the string names of these two functions? Fixes: PYSIDE-1670 Pick-to: 6.2 Change-Id: I14927995698726957ba8c515dddf5e37c21910ce Reviewed-by: Cristian Maureira-Fredes --- sources/pyside6/libpyside/feature_select.cpp | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'sources/pyside6/libpyside/feature_select.cpp') diff --git a/sources/pyside6/libpyside/feature_select.cpp b/sources/pyside6/libpyside/feature_select.cpp index 8b9834620..c82cccce1 100644 --- a/sources/pyside6/libpyside/feature_select.cpp +++ b/sources/pyside6/libpyside/feature_select.cpp @@ -44,6 +44,7 @@ #include #include +#include ////////////////////////////////////////////////////////////////////////////// // @@ -613,6 +614,34 @@ static PyObject *make_snake_case(QString s, bool lower) return String::getSnakeCaseName(s.toLatin1().data(), lower); } +PyObject *adjustPropertyName(PyObject *dict, PyObject *name) +{ + // PYSIDE-1670: If this is a function with multiple arity or with + // parameters, we use a mangled name for the property. + PyObject *existing = PyDict_GetItem(dict, name); // borrowed + if (existing) { + Shiboken::AutoDecRef sig(get_signature_intern(existing, nullptr)); + if (sig.object()) { + bool name_clash = false; + if (PyList_CheckExact(sig)) { + name_clash = true; + } else { + Shiboken::AutoDecRef params(PyObject_GetAttr(sig, PyName::parameters())); + // Are there parameters except self or cls? + if (PyObject_Size(params.object()) > 1) + name_clash = true; + } + if (name_clash) { + // PyPy has no PyUnicode_AppendAndDel function, yet + Shiboken::AutoDecRef hold(name); + Shiboken::AutoDecRef under(Py_BuildValue("s", "_")); + name = PyUnicode_Concat(hold, under); + } + } + } + return name; +} + static bool feature_02_true_property(PyTypeObject *type, PyObject *prev_dict, int id) { /* @@ -652,6 +681,9 @@ static bool feature_02_true_property(PyTypeObject *type, PyObject *prev_dict, in continue; PyObject *setter = haveWrite ? PyDict_GetItem(prev_dict, write) : nullptr; + // PYSIDE-1670: If multiple arities exist as a property name, rename it. + name = adjustPropertyName(prop_dict, name); + AutoDecRef PyProperty(createProperty(type, getter, setter)); if (PyProperty.isNull()) return false; -- cgit v1.2.3