Skip to content

Commit

Permalink
Switch PyObjCClass_HiddenSelector to return a new reference
Browse files Browse the repository at this point in the history
This enabled switching to PyDict_GetItemRef in that function.

Issue #608.
  • Loading branch information
ronaldoussoren committed Aug 6, 2024
1 parent ab8909e commit 79967c2
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 17 deletions.
6 changes: 3 additions & 3 deletions pyobjc-core/Modules/objc/method-accessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
return NULL; // LCOV_EXCL_LINE
}

if (meta && meta != Py_None) {
if (meta) {
if (PyObjCSelector_Check(meta)) {
/*
* KVO complicates things, it will insert an intermediate
Expand All @@ -136,24 +136,24 @@
/* AFAIK class methods cannot be used for KVO, ignore the
* issue here.
*/
Py_INCREF(meta);
return meta;
} else {
IMP sel_imp =
[PyObjCSelector_GetClass(meta) instanceMethodForSelector:sel];
IMP cur_imp = [PyObjCObject_GetObject(self) methodForSelector:sel];
if (sel_imp == cur_imp) {
Py_INCREF(meta);
return meta;
} else {
PyObjCMethodSignature* methinfo = PyObjCSelector_GetMetadata(meta);
if (methinfo == NULL) {
Py_DECREF(meta);
return NULL;
}
flattened = (char*)methinfo->signature;
}
}
}
Py_CLEAR(meta);
}

if (flattened == NULL) {
Expand Down
32 changes: 20 additions & 12 deletions pyobjc-core/Modules/objc/objc-class.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,12 @@
PyErr_Clear(); // LCOV_EXCL_LINE

} else {
PyObject* r = PyDict_GetItemWithError(hidden, v);
Py_DECREF(v);
if (r == NULL) {
if (PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
return NULL; // LCOV_EXCL_LINE
}

} else {
PyObject* r;
switch (PyDict_GetItemRef(hidden, v, &r)) {
case -1:
return NULL;
/* case 0: pass */
case 1:
return r;
}
}
Expand Down Expand Up @@ -1246,6 +1244,7 @@ static Class _Nullable objc_metaclass_locate(PyObject* meta_class)
// LCOV_EXCL_STOP

} else if (hidden) {
Py_DECREF(hidden);
continue;
}

Expand Down Expand Up @@ -1407,6 +1406,7 @@ static Class _Nullable objc_metaclass_locate(PyObject* meta_class)
return NULL; // LCOV_EXCL_LINE

} else if (hidden) {
Py_CLEAR(hidden);
continue;
}

Expand Down Expand Up @@ -1467,6 +1467,7 @@ static Class _Nullable objc_metaclass_locate(PyObject* meta_class)
Class cls;
Method m;
PyObject* dict = PyObjC_get_tp_dict((PyTypeObject*)base);
PyObject* hidden;

Py_BEGIN_ALLOW_THREADS
@try { /* XXX: Can this raise?, and is it necessary to give up the GIL here? */
Expand All @@ -1487,8 +1488,9 @@ static Class _Nullable objc_metaclass_locate(PyObject* meta_class)
return NULL;
}

if (PyObjCClass_HiddenSelector(PyObjCClass_ClassForMetaClass(base), sel, YES)
|| PyErr_Occurred()) {
hidden = PyObjCClass_HiddenSelector(PyObjCClass_ClassForMetaClass(base), sel, YES);
if (hidden || PyErr_Occurred()) {
Py_CLEAR(hidden);
return NULL;
}

Expand Down Expand Up @@ -1834,6 +1836,7 @@ static Class _Nullable objc_metaclass_locate(PyObject* meta_class)
if (hidden == NULL && PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
return NULL; // LCOV_EXCL_LINE
} else if (hidden) {
Py_CLEAR(hidden);
PyErr_SetObject(PyExc_AttributeError, name);
return NULL;
}
Expand Down Expand Up @@ -2005,6 +2008,7 @@ static Class _Nullable objc_metaclass_locate(PyObject* meta_class)
// LCOV_EXCL_STOP

} else if (hidden) {
Py_CLEAR(hidden);
Py_DECREF(value);

} else {
Expand Down Expand Up @@ -2371,6 +2375,7 @@ static Class _Nullable objc_metaclass_locate(PyObject* meta_class)
return NULL;
// LCOV_EXCL_STOP
} else if (hidden) {
Py_CLEAR(hidden);
continue;
}

Expand Down Expand Up @@ -3004,6 +3009,7 @@ Class _Nullable PyObjCClass_GetClass(PyObject* cls)
if (hidden == NULL && PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
return NULL; // LCOV_EXCL_LINE
} else if (hidden) {
Py_CLEAR(hidden);
(void)PyDict_SetItemString(info->sel_to_py, (char*)sel_getName(selector),
Py_None);
PyErr_Format(PyExc_AttributeError, "No selector %s", sel_getName(selector));
Expand Down Expand Up @@ -3403,8 +3409,9 @@ Class _Nullable PyObjCClass_GetClass(PyObject* cls)
}

r = 0;
if (!PyObjCClass_HiddenSelector(classObject, objcMethod->name,
PyObjCSelector_IsClassMethod(aMethod))) {
PyObject* hidden = PyObjCClass_HiddenSelector(classObject, objcMethod->name,
PyObjCSelector_IsClassMethod(aMethod));
if (!hidden) {
if (PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
r = -1; // LCOV_EXCL_LINE
} else if (PyObjCSelector_IsClassMethod(aMethod)) {
Expand All @@ -3414,6 +3421,7 @@ Class _Nullable PyObjCClass_GetClass(PyObject* cls)
r = PyDict_SetItem(extraDict, name, aMethod);
}
}
Py_CLEAR(hidden);

((PyObjCSelector*)aMethod)->sel_class = targetClass;

Expand Down
5 changes: 4 additions & 1 deletion pyobjc-core/Modules/objc/objc-object.m
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,8 @@
*
* Skip hidden methods.
*/
if (!PyObjCClass_HiddenSelector(base, sel, NO)) {
PyObject* hidden = PyObjCClass_HiddenSelector(base, sel, NO);
if (!hidden) {
if (PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
return NULL; // LCOV_EXCL_LINE
}
Expand All @@ -419,6 +420,7 @@
return NULL;
}
}
Py_CLEAR(hidden);
}
}

Expand Down Expand Up @@ -470,6 +472,7 @@
if (hidden == NULL && PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
return NULL; // LCOV_EXCL_LINE
} else if (hidden) {
Py_CLEAR(hidden);
continue;
}

Expand Down
8 changes: 7 additions & 1 deletion pyobjc-core/Modules/objc/selector.m
Original file line number Diff line number Diff line change
Expand Up @@ -969,12 +969,18 @@
return NULL; // LCOV_EXCL_LINE
}
if (PyObjCObject_IsMagic(self) || hidden) {
Py_CLEAR(hidden);
PyErr_Format(PyExc_AttributeError, "No attribute %s", name);
return NULL;
}
Py_CLEAR(hidden);

} else {
if (PyObjCClass_HiddenSelector(self, sel, YES)) {
PyObject* hidden;
hidden = PyObjCClass_HiddenSelector(self, sel, YES);

if (hidden) {
Py_CLEAR(hidden);
PyErr_Format(PyExc_AttributeError, "No attribute %s", name);
return NULL;
} else if (PyErr_Occurred()) { // LCOV_BR_EXCL_LINE
Expand Down

0 comments on commit 79967c2

Please sign in to comment.