← Home Archive About Support Also on Micro.blog
  • I’m having some type 2 fun with PyObjC while bringing its updates of reference counts closer to the patterns used by ARC.

    Objective-C using reference counting for memory management, similar to CPython. In modern code bases (and when using Swift) the compiler does this for you (“ARC”), but PyObjC still uses manual updates of the reference counts.

    PyObjC used CFRetain and CFRelease to increase and decrease the reference counts, instead of the more common [value retain] and [value release]. This made more sense during the time when Apple experimented with garbage collection years ago (basically before iPhone).

    It turns out that mixing the two can cause crashes in Objective-C code, e.g:

    NSURL* url = [NSURL alloc];  // new reference, caller must release
    CFRelease(url);
    

    Bisecting the PyObjC test suite to pinpoint the problem was annoyingly hard, especially when I fully expected that the root cause was a bug in my update instead of this. Luckily the fix was a lot easier: PyObjC will use retain and release methods to update reference counts going forward (starting with the upcoming 11.1 release).

    A second issue found while testing the 11.1 release. The following code will crash hard when compiled using ARC:

    #import <Foundation/Foundation.h>
    
    int main(void)
    {
         NSOutputStream* stream;
    
          stream = [NSOutputStream alloc];
          stream = [stream initToMemory];
    
          NSLog(@"%@", stream);
    }
    

    This is split calls to alloc and initToMemory are effectively what happens when using NSOutputStream.alloc().initToMemory() in Python. The workaround in PyObjC’s test suite is to create the stream using NSOutputStream.outputStreamToMemory(), working around Apple’s incorrect handling of reference counts.

    This appears to be a genuine bug in macOS, filed as FB17759654.

    → 1:03 AM, JAN 1
  • I’m happy to announce the 11.0 release of PyObjC, slightly delayed from the normal major release in October.

    This release has two major features:

    1. Support for the macOS 15.2 SDK, including new bindings for the frameworks MediaExtension and DeviceDiscoveryExtension

    2. Experimental support for GIL-less operation in the free-threaded build of Python 3.13

    The latter feature is an important reason for the delay: Supporting GIL-less operation required reworking parts of the internals of PyObjC, both to rely on other locks than the GIL and to avoid CPython APIs that are known to be problematic when the GIL isn’t present (“borrowed references” for anyone familiar with the CPython API).

    Free-threaded support is experimental at this point in time and has seen only limited testing for multi-threading. I’ve also focussed on getting the basics right, and have not worked at optimizing free-threading support. Expect improvements in future releases.

    With PyObjC 11 I’m dropping support for Python 3.8, given that that’s gone out of support by the CPython team.

    Finally, there’s a number of bug fixes and smaller features mentioned in the changelog.

    → 9:27 AM, JAN 14
  • RSS
  • JSON Feed
  • Micro.blog