aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/pyside.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/libpyside/pyside.cpp')
-rw-r--r--sources/pyside6/libpyside/pyside.cpp46
1 files changed, 44 insertions, 2 deletions
diff --git a/sources/pyside6/libpyside/pyside.cpp b/sources/pyside6/libpyside/pyside.cpp
index a832db28a..09acfea07 100644
--- a/sources/pyside6/libpyside/pyside.cpp
+++ b/sources/pyside6/libpyside/pyside.cpp
@@ -490,8 +490,10 @@ void initQApp()
setDestroyQApplication(destroyQCoreApplication);
}
-PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name)
+PyObject *getHiddenDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name)
{
+ using Shiboken::AutoDecRef;
+
PyObject *attr = PyObject_GenericGetAttr(self, name);
if (!Shiboken::Object::isValid(reinterpret_cast<SbkObject *>(self), false))
return attr;
@@ -505,6 +507,7 @@ PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *nam
}
// Mutate native signals to signal instance type
+ // Caution: This inserts the signal instance into the instance dict.
if (attr && PyObject_TypeCheck(attr, PySideSignal_TypeF())) {
auto *inst = Signal::initialize(reinterpret_cast<PySideSignal *>(attr), name, self);
PyObject *signalInst = reinterpret_cast<PyObject *>(inst);
@@ -517,13 +520,46 @@ PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *nam
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback); // This was omitted for a loong time.
- const char *cname = Shiboken::String::toCString(name);
int flags = currentSelectId(Py_TYPE(self));
int snake_flag = flags & 0x01;
+ int propFlag = flags & 0x02;
+
+ if (propFlag) {
+ // PYSIDE-1889: If we have actually a Python property, return f(get|set|del).
+ // Do not store this attribute in the instance dict, because this
+ // would create confusion with overload.
+ // Note: before implementing this property handling, the meta function code
+ // below created meta functions which was quite wrong.
+ auto *subdict = _PepType_Lookup(Py_TYPE(self), PyMagicName::property_methods());
+ PyObject *propName = PyDict_GetItem(subdict, name);
+ if (propName) {
+ // We really have a property name and need to fetch the fget or fset function.
+ static PyObject *const _fget = Shiboken::String::createStaticString("fget");
+ static PyObject *const _fset = Shiboken::String::createStaticString("fset");
+ static PyObject *const _fdel = Shiboken::String::createStaticString("fdel");
+ static PyObject *const arr[3] = {_fget, _fset, _fdel};
+ auto prop = _PepType_Lookup(Py_TYPE(self), propName);
+ for (int idx = 0; idx < 3; ++idx) {
+ auto *trial = arr[idx];
+ auto *res = PyObject_GetAttr(prop, trial);
+ if (res) {
+ AutoDecRef elemName(PyObject_GetAttr(res, PyMagicName::name()));
+ // Note: This comparison works because of interned strings.
+ if (elemName == name)
+ return res;
+ Py_DECREF(res);
+ }
+ PyErr_Clear();
+ }
+ }
+ }
+
+ const char *cname = Shiboken::String::toCString(name);
uint cnameLen = qstrlen(cname);
if (std::strncmp("__", cname, 2)) {
const QMetaObject *metaObject = cppSelf->metaObject();
QList<QMetaMethod> signalList;
+ // Caution: This inserts a meta function or a signal into the instance dict.
for (int i=0, imax = metaObject->methodCount(); i < imax; i++) {
QMetaMethod method = metaObject->method(i);
// PYSIDE-1753: Snake case names must be renamed here too, or they will be
@@ -560,6 +596,12 @@ PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *nam
return attr;
}
+// PYSIDE-1889: Keeping the old, misleading API for a while.
+PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name)
+{
+ return getHiddenDataFromQObject(cppSelf, self, name);
+}
+
bool inherits(PyTypeObject *objType, const char *class_name)
{
if (strcmp(objType->tp_name, class_name) == 0)