Bill Bumgarner


PyObjC 1.2 Released

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):

    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.
  • 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.

Comment on this post [ so far] ... more like this: [Mac OS X, PyObjC, Python] ... topic exchange: [Mac OS X, PyObjC, Python]

ReSTedit 0.50 Available


A build of ReSTedit 0.50 is available on my .mac file download page. It should "just work" on any Mac OS X 10.3 system as it includes both the pyobjc and docutils libraries within the app wrapper.

Beyond a handful of bug fixes, ReSTedit includes new features described in this post.

The README and ToDo list have also been updated.

Comment on this post [ so far] ... more like this: [Mac OS X, PyObjC, Python, ReSTedit, reStructured Text] ... topic exchange: [Mac OS X, PyObjC, Python, ReSTedit, reStructured Text]

Removing duplicate files

My sister received a new powerbook for Christmas and I'm in the process of moving her world from an old iMac to the new powerbook. I chose not to use the automatic migration tool because there are several years of garbage strewn across the old system's hard drive.

Somehow, my sister managed to duplicate a huge number of the thousands of digital photos in her iPhoto library. Some are duped many times and there were a number of copies of the photo library from various efforts to back it up. Worse, some of the "backups" had photos that weren't in the other libraries.

I needed something that could detect and remove duplicate files found within any random directory. I couldn't find a freeware tool that would work without lots of user interaction or did the dupe test in a fashion that I found reasonable.

So, I wrote a python script that does what I need. Maybe others will find it useful.

The latest version can be found at It is a one-off that solved a problem, not an attempt to write the world's best python script.

It works by:

  • launched via command line by passing a set of directories to be scanned
  • traverses all directories and groups all files by size
  • scans all sets of files of one size and checksums (md5) the first 1024 bytes
  • for all files that have the same checksum for the first 1024 bytes, checksums the whole file and collects together all real duplicates
  • deletes all duplicates of any one file, leaving the first encountered file as the one remaining copy

It is acceptably fast, processing 3.3 gigabytes of random files in only a few minutes (removing 1.2 gigabytes of duplicate files).

Comment on this post [ so far] ... more like this: [Mac OS X, Python] ... topic exchange: [Mac OS X, Python]