Archive for the 'PyObjC' Category

CocoaHeads San Jose

Monday, October 10th, 2005

I will be speaking at the CocoaHeads meeting on Thursday evening at the Apple campus. In particular, I’ll be focusing on PyObjC, including integration with various Tiger specific technologies, some history, and a focus on live demonstrations of the technology.

It will be rather freeform in nature. If anyone has any particular area of interest related to Python, Cocoa, and PyObjC, let me know.

PyObjC Article at ADC

Tuesday, August 16th, 2005

ADC has published Using PyObjC for Developing Cocoa Applications with Python. It is an excellent article that gives an overview of developing Cocoa applications using Python via PyObjC.

This article breaks some new ground for ADC, too. Specifically, it is the first article on ADC to use movies to help to explain the content. Jonathan ‘Wolf’ Rentzsch has posted an article explaining the details.

Good stuff.

PyObjC 1.3.7 Released

Wednesday, July 6th, 2005

PyObjC 1.3.7 has been released.

It includes:

  • Initial port to Mac OS X for Intel
  • Xcode 2.1 compatibility
  • Support for SenTestingKit and SecurityFoundation frameworks
  • Complete wrappers for DiscRecording framework
  • … a handful of other bug fixes …

Full details can be found in the NEWS file.

PyObjC on Intel based Mac OS X

Wednesday, June 8th, 2005

Ronald ported PyObjC to the Intel based Mac OS X environment last night. All of the unit tests pass except for the mach_inject related tests.

It took about 2 hours to do so. Not bad for having to port a nasty bit of assembly that constructs stack frames on the fly.

Nice.

PyObjC 1.3.6 is now available.

Wednesday, May 18th, 2005
DogSnake

Update: PyObjC 1.3.5 contained a bug that prevented plug-ins from working correctly. It has been fixed in 1.3.6.

PyObjC 1.3.6 is now available for download. This release adds support for many new features in Tiger, maintains backwards compatibility with Panther/Jaguar, and fixes many important bugs.

See the NEWS file for full details.

Some highlights:

  • The Xcode templates now use py2app. This means that development builds usually take less than a few seconds for a build from clean and considerably less than a second for incremental builds. Deployment builds will automatically create drag-n-droppable products for easy distribution.
  • in and inout parameters are fully supported. This includes the ability to pass NULL to the underlying API.
  • Core Data is fully supported. This includes py2app automatically compiling Core Data models from their development form into the runtime form.
  • A decorator is provided that allows easier specification of method signatures when using Python 2.4.
        @objc.signature(‘i@:if’)
        def methodWithX_andY_(self, x, y):
            return 0
  • NSData, NSDecimalNumber, and NSDate are now converted to appropriate native Python types automatically. serializePropertyList() and deserializePropertyList() can be used to convert an Obj-C property list to an NSData and back.
  • The proxy for pure Python objects acts more like a proper NSObject than before. This allows objects returned from pure Python libraries to be used from Objective-C in a more transparent fashion, including support for KVC.

Overall, this release really adds a tremendous amount of polish to PyObjC. Everything is very well tested and the behavior is just more consistent. Py2app has evolved significantly, as well, gaining Tiger specific features and many other refinements.

Great stuff. A huge thank you to Ronald and Bob. PyObjC is a production quality development tool that is truly a joy to work on and use.

OutlineEdit as a PyObjC application

Monday, May 2nd, 2005

The Tiger developer tools includes several Core Data examples, including OutlineEdit which demonstrates how to manage a hierarchical object graph and display said graph in an NSOutlineView.

PyObjC contains a python version of the same application.

The example’s setup.py also demonstrates how to set up a multiple document based application that compiles an Xcode created model file and sets up an Info.plist with several registered document types.

Using Core Data from Python

Sunday, May 1st, 2005

Update #1: Putting this at the top, because it is really important. The example changed since yesterday and this now requires top-of-tree [TOT] PyObjC. In particular, all of the methods that take NSError ** parameters now take one less argument, omitting the error argument, and return a tuple where the first element of the tuple is method’s normal return value and the second element is the resulting NSError, if any.

In other words, you will either receive a tuple of the form (result, None) or a tuple of the form (None, result), but never one that has both items set or both items set to None unless there is a bug in the underlying API.

The current TOT of PyObjC adds support for automatically adjusting the signatures of any methods that take NSError ** arguments. It is less than optimal in that there is no way to pass NULL for the error argument and, therefore, no way to indicate to the underlying framework that it should not pay the potentially expensive price of instantiating and composing the contents of an NSError* instance.

Someday, that will change. But it will be a hard change to make. So, for now, we have a working solution that supports everything needed to build full featured applications with a relatively minor performance penalty in relatively odd situations (it isn’t often that you would want to call one of these methods without collecting the error information).

These changes will be in PyObjC 1.3.1.


Via PyObjC, you can write Python applications that fully take advantage of Core Data.

PyObjC fully supports KVC, KVO, and subclassing of Objective-C from Python, so use of NSManagedObject is fully enabled.

One caveat: models edited in Xcode are saved in a “source” format that is “compiled” into a binary representation as a part of building a project. A compiler is provided to do exactly that and it is called via a standard build rule as a part of Xcode’s build process.

An example would best illustrate how to manually use Core Data from Python, including compiling a model. In this example, we compile the model from the EventManager Core Data example.

First, link momc to somewhere easily accessed (this is all one line and assumes that ~/bin/ exists):

ln -s /Library/Application\ Support/Apple/Developer\ Tools/Plug-ins/XDCoreDataModel.xdplugin/Contents/Resources/momc ~/bin/momc

Then, compile the sample model and copy the CranberryFestival sample data to someplace useful:

mkdir test
cd test
momc /Developer/Examples/CoreData/EventManager/MyDocument.xcdatamodel em.mom
cp /Developer/Examples/CoreData/EventManager/Sample\ Event\ Files/CranberryFestival.events .

Now, to fire up python and work with Core Data. This assumes top of tree of PyObjC or the next production release. I ripped out the ‘>>>’ characters for copy/paste convenience. Anywhere Python normally spews something, the output shows up in italics.

First, create the managed object model (and spew a little information about an entity within):

from CoreData import *
momURL = NSURL.fileURLWithPath_("em.mom")
mom = NSManagedObjectModel.alloc().initWithContentsOfURL_(momURL)
mom.entities().valueForKey_("name")
(Event, EventParticipant, Location, Occasion, Person)
eventEntity = mom.entitiesByName()['Event']
eventEntity.attributesByName().keys()
(eventID, detailDescription, endTime, name, startTime, date)

Now, set up the persistent store coordinator and managed object context:

dataURL = NSURL.fileURLWithPath_("CranberryFestival.events")
psc = NSPersistentStoreCoordinator.alloc().initWithManagedObjectModel_(mom)
psc.addPersistentStoreWithType_configuration_URL_options_error_(None, None, dataURL, None)
(, None)
moc = NSManagedObjectContext.new()
moc.setPersistentStoreCoordinator_(psc)

Finally, fetch some Events and display some information:

fetch = NSFetchRequest.new()
fetch.setEntity_(eventEntity)
events, error = moc.executeFetchRequest_error_(fetch)
len(e)
5
for anEvent in events:
  print anEvent.valueForKey_(u'name')
Opening Ceremony
Registration
Lunch by the Bog
Pick your own Cranberries
Educational Workshop

Of course, you can always take the same approach as the Core Data Document Based Application and do everything via Interface Builder and Xcode, thus automating all of this per NSPersistentDocument.

PyObjC adds support for Tiger specific technologies

Friday, April 29th, 2005
dogsnake

PyObjC has gained support for multiple frameworks that are new in Tiger. This includes Core Data, Automator and Xgrid.

See the NEWS file for details.

You will need to check out the PyObjC source to take advantage of the new features. Version 1.3 will be released in the very near future. As always, the code in the repository is extremely stable.

svn co http://svn.red-bean.com/pyobjc/trunk/pyobjc/

Big improvements to PyObjC

Tuesday, January 18th, 2005

Bob made a bunch of improvements to PyObjC. Go read the post for details. Some very cool stuff.

PyObjC 1.2 Released

Wednesday, December 29th, 2004

PyObjC PyObjC v1.2 is now available. You can grab it from the sourceforge download page or from my idisk.

The major changes are listed below. There is some seriously cool stuff in here; new packaging, support for pure-python loadable NSBundles, categories, better bridging of complex types, and revamped examples.

  • PyObjCTools.AppHelper.stopEventLoop will attempt to stop the current
    NSRunLoop (if started by runConsoleEventLoop) or terminate the
    current NSApplication (which may or may not have been started by
    runEventLoop).
  • This version no longer support Python 2.2. Python 2.3 or later is
    required.
  • It is now possible to use reload on modules containing Objective-C
    classes.
  • objc.loadBundle now returns bundle we just loaded.
  • Added objc.loadBundleVariables and objc.loadBundleFunctions,
    two functions for reading global variables and functions from a bundle.
  • objc.runtime will now raise AttributeError instead of objc.nosuchclass_error
    when a class is not found.
  • objc.Category can be used to define categories on existing classes:
    class NSObject (objc.Category(NSObject)):
        def myMethod(self):
            pass
    

    This adds method myMethod to class NSObject.

  • py2app is now used for all Example scripts and is the recommended method
    for creating PyObjC applications.
  • Proxies of dict, list, and tuple now respect the invariant that you should
    get an identical instance if you ask for the same thing twice and the
    collection has not been mutated. This fixes some problems with binary
    plist serialization, and potentially some edge cases elsewhere.
  • There is now a __bundle_hack__ class attribute that will cause the PyObjC
    class builder to use a statically allocated class wrapper if one is
    available via certain environment variables. This functionality is used
    to enable +[NSBundle bundleForClass:] to work for exactly one class from
    a py2app-created plugin bundle.
  • We now have a working Interface Builder palette example due to
    __bundle__hack__.
  • bool(NSNull.null()) is now false.
  • setup.py supports several new commands:
    * build_libffi
    
      builds libffi (used by build_ext)
    
    * build_html
    
      builds html documentation from ReST source
    
    * bdist_dmg
    
      creates a disk image with the binary installer
    
    * bdist_mpkg
    
      creates a binary installer
    
    * test
    
      runs unit test suite (replaces Scripts/runPyObjCTests
      and Scripts/runalltests)
    
  • PyObjCStrBridgeWarning can now be generated when Python str objects
    cross the bridge by calling objc.setStrBridgeEnabled(False). It is
    HIGHLY recommended that your application never send str objects over
    the bridge, as it is likely to cause problems due to the required
    coercion to unicode.
  • The coercion bridge from Python to Objective-C instances can now be
    augmented from Python as it is exposed by OC_PythonObject. See
    objc._bridges. This is how the str -> unicode -> NSString
    bridge with optional warnings is implemented.
  • The coercion bridge between Python objects and Objective-C structures
    can now be augmented from Python as it is exposed by OC_PythonObject.
    See objc._bridges. This is how the Carbon.File.FSRef
    <-> '{FSRef=[80c]}' structure bridge is implemented.
  • Extension modules such as _objc, _AppKit, etc. are now inside
    packages as objc._objc, AppKit._AppKit, etc. They should never be
    used directly, so this should not break user code.