Thursday, July 19, 2007

a sneak preview of PyObjC 2.0

The development of PyObjC has slowed down to a standstill, or so it would seem if you look the website or subversion repository. That's far from the truth however, I've been hard at work on a major new version of PyObjC and the effort is paying of.

The new version isn't in the public repository yet however because I'm targeting Leopard (Objective-C) and haven't separated the Leopard specific code and examples from the bits that are safe for Leopard. In case anyone is starting to get very worried: PyObjC still supports Tiger through a compatibility layer.

The new version sport some major new versions, hence the major update to the version number:
  • Full support for CoreFoundation-based frameworks such as Core Graphics and other parts of the Quartz graphics layer. This includes access to all APIs in Core Graphics instead of the rather more limited bindings that Apple ships.

    I have several examples for this, including Python ports for all examples in the (excellent) book "Programming with Quartz".

  • Class methods are finally true first-class citizens. It is now possible to access all class methods directory through the class without going through the pyobjc_classMethods attribute. This fixes a longstanding bug in PyObjC and gives a more natural access to class methods whose name shadows an instance method (such as NSObject.description).

  • Creating typed instance variables is now more convenient, as is creating instance variables in general. Compare the old way:


    class MyClass (NSObject):
    var1 = objc.ivar("var1")
    active = objc.ivar("var1", type=objc._C_BOOL)


    and the new way:


    class MyClass (NSObject):
    var1 = objc.ivar()
    active = objc.ivar.bool()
    .

    It is also no longer necessary to mention the name of IBOutlets twice.

  • PyObjC is split into a core package that contains the actual bridge and a set of add-on packages that provide the wrappers for frameworks and make it possible to type import Foundation instead of loading the framework by hand.

    This makes development easier, and more importantly makes sure that the infrastructure for creating framework wrappers is sufficiently public thereby making it easier for others to provide bindings to their own frameworks.

  • Output arguments are treated slightly different: you must now pass a place holder value (either None or objc.NULL) instead of leaving the argument out. This makes it even easier to translate between Objective-C documentation or code samples and Python and also makes is possible to tell the method that you're not interested in the output value (by passing in objc.NULL).

    The old behaviour is still supported but will give a deprecation warning.

  • The module PyObjCTools.NibClassBuilder is also on the way out. Using it is still supported and doesn't generate deprecation warnings, but the the module is formally deprecated.

    There are several reasons for this, one of them is that the mechanism that this module uses to extract class information from NIB files doesn't always work correctly in localized applications (localization tools won't always copy the required information because that information isn't used by Objective-C code).



These are the major new features that are interesting for users of PyObjC, there's some cleanup work and a major implementation change to make maintaining framework wrappers a lot easier.

We used to have a largish set of obscure calls to objc.setSignatureForSelector and manually written method wrappers to make sure that PyObjC did the right thing for methods whose interface is non-trivial, such as methods that have pass-by-reference arguments or pointers to C arrays of values.

Maintaining these is annoyingly hard and I'm glad that this is for the most part no longer necessary. The core of PyObjC can now process the metadata format defined by the BridgeSupport project.

This makes maintenance of framework wrappers a lot more easier because we've no longer have to maintain cryptic signature strings but can instead rely on a tool to extract most information from the header files (with an exception mechanism to steer that tool when it doesn't quite do the right thing). This metadata file also takes a way the need for most manually written method wrappers.

The best part of this is that maintenance of these metadata files can be shared between the users and developers of a number of language bridges and with some luck framework authors will start shipping metadata files with their frameworks.

8 comments:

schwa said...

Hi Ronald,

This is absolutely awesome and I'm really looking forward to PyObjc 2.0.

Two questions (not sure you can answer either of them):

1) Is PyObjc 2.0 going to make it into Leopard?

2) Where is PyObjc 2.0 development taking place? As pointed out PyObjc in subversion seems to be asleep. I'd love to look at how PyObjc 2.0 interacts with BridgeSupport but the code isn't available.

Paul Bissex said...

This is great to hear! You should absolutely post an update to the PyObjC site.

Ronald Oussoren said...

schwa: PyObjC 2.0 development is taking place in a closed repository. I want to start pushing the code that isn't touched by Leopard's NDA into a branch in the public repository, but do have to find some time to actually do that.

I won't comment on any features of Leopard or PyObjC's interaction with those other than to say that it is my goal to fully support all Objective-C and most CF-based frameworks in the future.

Anonymous said...

Great! I'm looking forward to PyObjC 2.0, too. But what about pickling objective-c objects?

Ορέστης said...

Good to know. I'd like also a new version of PyObjC aimed at Tiger so it can be used now. I also think an update to the site is in order.

Thanks for your effort!

Anonymous said...

As a python developer Im really looking forward to seeing this in action.

But are there any plans to make http://pyobj.sf.net (or any other homepage if the project moves) seem active. Right now its one of those things that potential developers look at and thinks: "Hmm, this doesnt seem that much supported, so I better do something else."

Thumbs up for the great work :)

chuckfletcher said...

What are the odd of being able to use pyObjC 2.0 to develop 3rd party native iphone applications? Currently all the iphone development is with objective-c and coregraphics (UIkit, vs Appkit/Cocoa).

Thanks,

Chuck

Ronald Oussoren said...

Revar: using PyObjC to develop native applications for the iPhone should be possible, but there are some major hurdles to cross before that happens.

The most important of those is that there is port of libffi to the iPhone yet (AFAIK).

A non-technological hurdle is that I don't want to work on such a port because I live in an iPhone-less country (Holland).