On 17 May 2014, at 16:42, Marc Van Olmen <marc@acclivitynyc.com> wrote:


Just switched our app over to PyObjc 3.0 and XCode 5.1.1

biggest change I had to do was to change super to pyobjc.super, and just fixed a few 10.8 warnings of deprecated methods.

objc.super is also needed on older versions of PyObjC, it is just much, much easier to trigger problems with PyObjC 3.0 due to the removal of some hacks from the bridge implementation :-)

One issue I notice that that PyObjc warnings is on in debug mode of the app:

and  I get a lot of these

2014-05-17 10:35:59.072 Checkout[51943:303] *** ObjC exception 'NSRangeException' (reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]') discarded
Stack trace (most recent call last):
  PyObjCNativeSelector_Type (in _objc.so) + 0
  objcsel_call (in _objc.so) + 228
  PyObjCFFI_Caller (in _objc.so) + 3305
  ffi_call (in _objc.so) + 125
  ffi_call_SYSV (in _objc.so) (x86-darwin-Kjl12T.s:63)
  -[__NSArrayM objectAtIndex:] (in CoreFoundation) + 251
  objc_exception_throw (in libobjc.A.dylib) + 230
  NSExceptionHandlerExceptionRaiser (in ExceptionHandling) + 211

this one for example is generated by this iterator:

        # Categorize devices
        for keyboard in DDHidLib.DDHidKeyboard.allKeyboards():
            # Don't recheck devices that have been categorized already
            # NSLog(u'%@', unicode(keyboard.descriptionDictionary()))

Also this iterator is causing exceptions:

         for subview in self.tabView.subviews():
if subview.isKindOfClass_(SFTabButton):
            tabsByOriginXDict[Foundation.NSMinX(subview.frame())] = subview

but I see a common issue for this.

I could add changes to this: (but I will wait for you input.)

def nsarray__getitem__(self, idx):
    if isinstance(idx, slice):
        start, stop, step = idx.indices(len(self))
        return [self[i] for i in range(start, stop, step)]

    elif not isinstance(idx, INT_TYPES):
        raise TypeError("index must be a number")

    if idx < 0:
        idx += len(self)
        if idx < 0:
            raise IndexError("list index out of range")

    return container_unwrap(self.objectAtIndex_(idx), RuntimeError)

I can reproduce the problem with a simple script:

# t.py
import objc
from PyObjCTools import Debugging

NSArray = objc.lookUpClass('NSArray')
a = NSArray.arrayWithArray_(['a', 'b', 'c'])


$ python3 t.py
['a', 'b', 'c']
2014-05-30 11:34:11.195 Python[33077:d07] *** ObjC exception 'NSRangeException' (reason: '*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]') discarded
Stack trace (most recent call last):
  ffi_call_unix64 (in _objc.so) + 79
  -[__NSArrayI objectAtIndex:] (in CoreFoundation) + 175
  objc_exception_throw (in libobjc.A.dylib) + 43
  NSExceptionHandlerExceptionRaiser (in ExceptionHandling) + 172
['a', 'b', 'c']

The problem is twofold:

1) PyObjCTools.Debugging complains too much: there is a range exception, but it is caught and handled by Python code

    I don’t know yet what I can do about this.

2) NSArray no longer has an __iter__ method, that got lost in the PyObjC 3.0 cleanup. I’m re-adding this method later today.

The __iter__ method got lost due to a fairly major change in how Cocoa classes are handled by PyObjC: before 3.0 I scanned the method table of Cocoa classes as soon as they were touched and used the list of methods to determine which informal protocols the class appeared to implement and used that information to add a Python interface to classes (e.g. add __getitem__ when a class implements “objectForKey:”). That  code was fairly expensive because it effectively got called every time a Cocoa object was touched from Python because Cocoa classes can be updated at runtime and there is no way to get notified when a class is changed. Therefore PyObjC 3.0 only looks for names that are explicitly used from Python, and specials methods are added to specific classes only.  The NSArray.__iter__ method got lost during the transition to this new implementation :-(



On Mar 7, 2014, at 11:34 AM, Marc Van Olmen <marc@acclivitynyc.com> wrote:

On Mar 4, 2014, at 6:50 AM, Ronald Oussoren <ronaldoussoren@mac.com> wrote:

I guess it really time to push out a new release.

The PyObjC version in the repository (a 3.0 prerelease) builds cleanly with Xcode 5 on OSX 10.9. To be honest I’m not sure if the current public release builds cleanly on 10.9 because I haven’t used it in a long time.

That would be nice, we are planning a major release of Checkout 4.0 in upcoming weeks, would be nice to go beta with PyObjc 3.0 release)