[PyObjC-svn] r2263 - trunk/pyobjc/pyobjc-core/Modules/objc
[email protected] Sat, 11 Jul 2009 04:09:20 -0500
| Newsgroups | gmane.comp.python.pyobjc.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: ronaldoussoren
Date: Sat Jul 11 04:09:20 2009
New Revision: 2263
Log:
Fix issue where KVC could result in an infinite recursion loop.
Modified:
trunk/pyobjc/pyobjc-core/Modules/objc/class-builder.m
trunk/pyobjc/pyobjc-core/Modules/objc/objc-object.m
Modified: trunk/pyobjc/pyobjc-core/Modules/objc/class-builder.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/class-builder.m (original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/class-builder.m Sat Jul 11 04:09:20 2009
@@ -2093,8 +2093,16 @@
objc_superSetReceiver(spr, self);
*((id *)retval) = (id)objc_msgSendSuper(&spr, _meth, key);
NS_HANDLER
+
/* Parent doesn't know the key, try to create in the
* python side, just like for plain python objects.
+ *
+ * NOTE: We have to be extermely careful in here, some classes,
+ * like NSManagedContext convert __getattr__ into a -valueForKey:,
+ * and that can cause infinite loops.
+ *
+ * This is why attribute access is hardcoded using PyObjCObject_GetAttrString
+ * rather than PyObject_GetAttrString.
*/
if (([[localException name] isEqual:@"NSUnknownKeyException"]
) && [[self class] accessInstanceVariablesDirectly]) {
@@ -2104,10 +2112,10 @@
PyObject *res = NULL;
r = -1;
do {
- res = PyObject_GetAttrString(selfObj, (char *)[key UTF8String]);
+ res = PyObjCObject_GetAttrString(selfObj, (char *)[key UTF8String]);
if (res == NULL) {
PyErr_Clear();
- res = PyObject_GetAttrString(selfObj, (char *)[[@"_" stringByAppendingString:key] UTF8String]);
+ res = PyObjCObject_GetAttrString(selfObj, (char *)[[@"_" stringByAppendingString:key] UTF8String]);
if (res == NULL) {
break;
}
Modified: trunk/pyobjc/pyobjc-core/Modules/objc/objc-object.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/objc-object.m (original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/objc-object.m Sat Jul 11 04:09:20 2009
@@ -272,6 +272,7 @@
}
+
static PyObject *
object_getattro(PyObject *obj, PyObject * volatile name)
{
@@ -947,3 +948,19 @@
((PyObjCObject*)object)->objc_object, object);
((PyObjCObject*)object)->objc_object = nil;
}
+
+PyObject* PyObjCObject_GetAttr(PyObject* obj, PyObject* name)
+{
+ return object_getattro(obj, name);
+}
+
+
+PyObject* PyObjCObject_GetAttrString(PyObject* obj, char* name)
+{
+ PyObject* pyname = PyString_FromString(name);
+ if (pyname == NULL) return NULL;
+
+ PyObject* rv = object_getattro(obj, pyname);
+ Py_DECREF(pyname);
+ return rv;
+}
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge