Fun with async...

One of my plans for a future version of PyObjC is to add pervasive support for asyncio. This will in the end result in two changes to PyObjC:

  1. Add an implementation of an asyncio event loop that is implemented on top of Apple’s NSRunLoop and CFRunLoop

  2. Add “async” methods to Cocoa classes too change callback style programming with completion handlers into more or less standard async Python code.

To experiment with the latter I’ve created a small and crude script that lets me call the geocoder from CoreLocation in an async manner:

    async def main(adress):
        coder = CoreLocation.CLGeocoder.alloc().init()
        placemarks, error = await coder.geocodeAdressString_(address)
        print(f"placemarks: {placemarks}")
        print(f"error: {error}")

This looks a lot nicer than the usual callback based code.

A link to the full script:. Most of the linked to script is support code that should mostly go away when I get around to adding an asyncio event loop to PyObjC.

For some reason “hg pull -u” fails on macOS 10.14.1 beta (in a VM) with a broken pipe message from ssh . Adding “IPQoS lowdelay throughput” to ~/.ssh/config makes it work again. Sigh…

PyObjC 5.1 released

I’ve pushed PyObjC 5.1 to PyPI. This is a minor feature release with the following changes:

  • Instances of most builtin value types and sequences (int, float, str, unicode, tuple, list, set, frozenset and dict) can now be written to archives that require secureCoding.

  • Xcode 10 “GM” contains one difference from the last beta: the constant MLComputeUnitsCPUAndGPU in the CoreML bindings.

  • Add a proxy for C’s “FILE*” type on Python 3. This is not necessary on Python 2 because the default IO stack on Python 2 already uses FILE* internally.

    This proxy type is very minimal and shouldn’t not be used for general I/O.

  • Bindings are up-to-date w.r.t. Xcode 10.1 (beta)

  • Updated the support code for framework wrappers to be able to emit deprecation warnings on the first import of a deprecated constants (functions and methods will only raise a deprecation warning when called).

    This is just an infrastructure change, the actual framework bindings do not yet contain the information used to emit deprecation warnings.

  • Add metadata for deprecation warnings to the “Contacts” framework

  • Import ABCs from collections.abc instead of collections because the latter is deprecated.

PyObjC 5.0 is out

The release of macOS 10.14 is near, it is therefore time to release a new major version of PyObjC. I’ve uploaded PyObjC to PyPI, it can be installed using “python3 -m pip install -U pyobjc”.

What is PyObjC

The PyObjC project provides bindings to most of Apple’s higher-level APIs (frameworks). More information about these bindings and how to use PyObjC can be found on the PyObjC website.

What is new

The main feature of this release is the addition of support for APIs introduced in macOS 10.14 (Mojave).

In particular:

  • Adds support for macOS 10.14 (Mojave)

    This release updates the framework wrappers with support for new APIs in macOS 10.14 and adds bindings for the following new frameworks:

    • AdSupport
    • CoreAudio (new in macOS 10.0)
    • CoreAudioKit (new in macOS 10.4)
    • CoreMedia (new in macOS 10.7)
    • CoreMediaIO (new in macOS 10.7)
    • DiscRecording (new in macOS 10.2)
    • DiscRecordingUI (new in macOS 10.2)
    • DVDPlayback (new in macOS 10.3)
    • MediaToolbox
    • NaturalLanguage
    • Network
    • OSAKit (new in macOS 10.4)
    • UserNotifications
    • VideoSubscriberAccount
    • VideoToolbox (new in macOS 10.8)
    • Added two features that can help with gating code on the version of macos:

    1) The constants “objc.MAC_OS_X_VERSION_CURRENT” can be compared with one of the “objc.MAC_OS_X_VERSION_…” contants.

    2) The function “objc.macos_avaiable(major, minor[, patch])” returns true if the current macOS version is at least the specified version, comparable with “@available” in Swift.

  • PR19: Fix deprecation warning in bridgesupport support module

    Patch by: Mickaël Schoentgen

  • Creating objc.ObjCPointer instances now results in a Python warning, instead of an unconditional message on stdout.

  • System bridgesupport XML files (normally not used by PyObjC) can contain constant numbers with value “inf”, PyObjC now knows how to handle those.

  • Added bindings for the “Metadata” subframework of the “CoreServices” framework.

  • Added bindings for the “CarbonCore” subframework of the “CoreServices” framework.

    Most APIs in this subframework are not available to Python, only those APIs that are not deprecated and seem interesting are exposed.

  • The separate framework wrappers DictionaryServices, LaunchServices and SearchKit are deprecated, use the CoreServices bindings instead.

    These framework wrappers still exists, but are effectively aliases for CoreServices with this release. Because of this these bindings can expose more symbols than previously.

  • Fix unexpected exception when trying to call getattr on a framework wrapped with a name that isn’t a valid identifier.

  • Issue 244: Bad metadata for CGPDFOperatorTableSetCallback

  • Issue 247: Fix crash in regression test case

    One specific test in pyobjc-core crashed the interpreter when run separately. Because of this I’ve disabled an optimization that uses alloca instead of PyMem_Malloc to allocate memory for now.

Supporting development

I do all development on PyObjC in my spare time. Please consider donating if you use PyObjC professionally. This will help me to improve PyObjC and related projects. See my website for more information.

I justed uploaded PyObjC 5.0b1 to PyPI. This fixes a number of bugs in PyObjC 5.0a1 and includes binary wheels for all supported Python versions.

More PyObjC work

Worked on PyObjC a bit during the day, in particular on manual bindings for a couple of more complex APIs that cannot be described in PyObjC’s metadata system.

The framework bindings now pass on macOS 10.14, except for 3 newly wrapped frameworks that require some more manual bindings.

I should be on track to finish PyObjC 5.0 before macOS 10.14 reaches GM.

First alpha release for PyObjC 5.0

I pushed a first alpha release for PyObjC 5.0 to PyPI, it can be installed with “pip install –pre pyobc”.

The major change in the 5.0 release is the addition of API bindings for macOS 10.14. This release is mostly up-to-date w.r.t. developer beta 3 of that release.

Other than updating existing API bindings this release adds new framework bindings for the following frameworks:

  • AdSupport
  • CoreAudio (new in macOS 10.0)
  • CoreAudioKit (new in macOS 10.4)
  • CoreMedia (new in macOS 10.7)
  • CoreMediaIO (new in macOS 10.7)
  • DiscRecording (new in macOS 10.2)
  • DiscRecordingUI (new in macOS 10.2)
  • DVDPlayback (new in macOS 10.3)
  • MediaToolbox
  • NaturalLanguage
  • Network
  • OSAKit (new in macOS 10.4)
  • UserNotifications
  • VideoSubscriberAccount

The bindings for CoreAudio, CoreMedia and MediaToolbox aren’t fully usable in this release, I have to write C code for a number of APIs and data structures that cannot be accessed using the generic FFI in pyobjc-core.

This alpha release only included wheels for the 64-bit installer of Python 3.7 (the default download on Python.org), the final release will include the full set of wheels.

Footnote

The release is a week later and less complete than I had hoped earlier. The reason for that is primarily that I was too optimistic on the amount of work I’d be able to do before and during EuroPython. In the end I barely touched my computer for PyObjC work at EuroPython, and not at all during the trip around Scotland beforehand (both of which were good for me, but less so for making progress)