<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>bbum&#039;s weblog-o-mat &#187; PyObjC</title>
	<atom:link href="http://www.friday.com/bbum/category/science/technology/pyobjc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.friday.com/bbum</link>
	<description>...so google can index my head.</description>
	<lastBuildDate>Sun, 12 Feb 2012 05:38:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Calling Python from Objective-C</title>
		<link>http://www.friday.com/bbum/2009/11/21/calling-python-from-objective-c/</link>
		<comments>http://www.friday.com/bbum/2009/11/21/calling-python-from-objective-c/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 07:16:31 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=1613</guid>
		<description><![CDATA[Every six months or so, I run across a question along the lines of how do I invoke some Python code from Objective-C? Kinda like here for which I posted the same conceptually concrete but technically vague pattern that I have posted for the last decade+. Which led to this question. OK &#8212; enough is [...]]]></description>
			<content:encoded><![CDATA[<p>Every six months or so, I run across a question along the lines of <em>how do I invoke some Python code from Objective-C?</em></p>
<p>Kinda like <a href="http://stackoverflow.com/questions/1308079/calling-python-from-objective-c/1308469">here</a> for which I posted the same conceptually concrete but technically vague pattern that I have posted for the last decade+.</p>
<p>Which led to <a href="http://stackoverflow.com/questions/1772491/call-from-objective-c-into-python">this question</a>.</p>
<p>OK &#8212; enough is enough.  Here is a working example.<span id="more-1613"></span>Specifically, you&#8217;ll want to grab <a href="http://svn.red-bean.com/bbum/trunk/PyObjC/CallPythonFromObjectiveC/">the source</a>:</p>
<pre>svn co http://svn.red-bean.com/bbum/trunk/PyObjC/CallPythonFromObjectiveC/</pre>
<p>You should be able to open the Xcode Project contained within, build it, and then (on Snow Leopard, anyway):</p>
<blockquote><p>python call-python-from-objc.py /path/to/built/AbstractClassDefinition.bundle
</p></blockquote>
<p>And it&#8217;ll spew something like:</p>
<pre>creating Bob
returning new instance &lt;Concrete 4346092816 named Bob>
2009-11-20 22:44:49.485 Python[41780:d07] Created instance: &lt;Concrete 4346092816 named Bob>
factor will be 1000000000
2009-11-20 22:44:49.486 Python[41780:d07] Set the fudge factor. Gonna do it up, now.
doing it returning 927.3
Did it! 1000000000 927.299988
</pre>
<p>The Xcode project produces an NSBundle that contains two unrelated pieces of source; an Abstract Class that is subclassed by python to provide the binding from Objective-C into Python and a class that provides an Objective-C method invoked by the python script to demonstrate calling from Obj-C into Python.</p>
<p>The Abstract Class is the first piece of the puzzle.  It is declared as:</p>
<pre>@interface AbstractClass : NSObject {
    NSString *name;
}
@property(copy) NSString *name;
@property unsigned long long fudgeFactor;
+ namedInstance: (NSString *) aName;
- (float) doItToIt: (BOOL) fastFlag;
@end
</pre>
<p>That is, a pretty straightforward (and totally contrived) Objective-C class.  The <em>Abstract</em> part is that this class is not designed to be directly instantiated.  Instead, it is too be subclassed and the subclass is the bit that is instantiated, as is indicated by the implementation:</p>
<pre>void SubclassResponsibility(id classOrInstance, SEL _cmd) {
    NSString *reason = [NSString stringWithFormat: @"Must subclass %s and override the method %s.",
       object_getClassName(classOrInstance), sel_getName(_cmd)];
    @throw [NSException exceptionWithName: @"SubclassResponsibility"
       reason: reason
       userInfo: nil];
}
@implementation AbstractClass
@synthesize name;
- (void) setFudgeFactor:(unsigned long long) aShort
{
    SubclassResponsibility(self, _cmd);
}
- (unsigned long long) fudgeFactor
{
    SubclassResponsibility(self, _cmd);
    return 0;
}
+ namedInstance: (NSString *) aName
{
    SubclassResponsibility(self, _cmd);
    return nil; // not reaached
}
- (float) doItToIt: (BOOL) fastFlag;
{
    SubclassResponsibility(self, _cmd);
    return 0.0; // not reached
}
@end
</pre>
<p>Note that the <em>Subclass Responsibility</em> pattern used to be quantified in the Pre-OpenStep version of the what-is-now-called-Cocoa APIs.  Object &#8212; the then NSObject &#8212; actually declared a <code>-subclassResponsibility:(SEL)</code> method!</p>
<p>The <code>call-python-from-objc.py</code> does the following:</p>
<p>1. Loads the bundle containing the implementation of <code>AbstractClass</code>: </p>
<pre>bundle = Foundation.NSBundle.bundleWithPath_(bundlePath)
if not bundle.principalClass():
    print "%s: failed to load bundle." % sys.argv[0]
</pre>
<p>2. Creates a subclass of <code>AbstractClass</code>:</p>
<pre>AbstractClass = objc.lookUpClass("AbstractClass")
class ConcreteClass(AbstractClass):
    _fudgeFactor = 0
    # factory method
    @classmethod
    def namedInstance_(self, aName):
        print "creating %s" % aName
        newInstance = ConcreteClass.new()
        newInstance.setName_(aName)
        print "returning new instance %s" % newInstance
        return newInstance
    # fudgeFactor property stored in Python subclass
    def fudgeFactor(self):
        return self._fudgeFactor
    def setFudgeFactor_(self, aFactor):
        print "factor will be %s" % aFactor
        self._fudgeFactor = aFactor
    # the method that does it all, so to speak
    def doItToIt_(self, fastFlag):
        if fastFlag:
            returnValue = 516.295
        else:
            returnValue = 927.3
        print "doing it returning %s" % returnValue
        return returnValue
    # Describe instances more pythonically
    def description(self):
        return "<concrete %s named %s>" % (id(self), self.name())
</concrete></pre>
<p>3. Invoke a random bit of Python code that calls an Objective-C method that calls back into Python</p>
<pre>objectiveCCode = objc.lookUpClass("ObjectiveCCallingPython")
print objectiveCCode.callSomePython()
</pre>
<p>More specifically, the class <code>ObjectiveCCallingPython</code> exists solely as a demonstration of calling from Objective-C into Python.  It happens to be implemented in the same bundle as <code>AbstractClass</code>, but it doesn&#8217;t need to be.</p>
<p>The <code>callSomePython</code> method looks like:</p>
<pre>+ (NSString *) callSomePython;
{
    Class concreteClass = NSClassFromString(@"ConcreteClass");
    AbstractClass *concreteInstance = [concreteClass namedInstance: @"Bob"];
    NSLog(@"Created instance: %@", concreteInstance);
    concreteInstance.fudgeFactor = 1000000000;
    NSLog(@"Set the fudge factor. Gonna do it up, now.");
    float value = [concreteInstance doItToIt: NO];
    return [NSString stringWithFormat: @"Did it! %llu %f", concreteInstance.fudgeFactor, value];
}
</pre>
<p>Straightforward;  grab the concrete subclass defined in Python, instantiate, configure, then tell it to do something.</p>
<p>The key is use Objective-C as the bridge between the compiled language (C/C++/Objective-C) and the interpreted language (this same pattern will work for other bridges).   The easiest way to do that is to define an abstract class in Objective-C that is then subclasses in the interpreted language.   From the compiled code, the abstract class acts as the source for all of the compiled type information the compiler needs.   From the interpreted code, the abstract class&#8217;s stub method implementations provide the runtime metadata necessary to allow the interpreter to correctly convert between compiled and interpreted data types.</p>
<p>Or, a specific example, the <code>fudgeFactor</code> property has stub method implementations that enforce subclass responsibility. Beyond that, the presence of said methods ensure that the Python implemented method implementations contain the correct metadata such that the doesn&#8217;t-fit-in-an-id type of the argument to the setter and return value of the getter is correctly handled.</p>
<p>There are about a bazillion different variations possible, including eliminating the Abstract class.  Ultimately, the key to success is ensuring that both sides of the bridge have all metadata necessary to work correctly.  For the C/ObjC/C++ compiler, it needs the types of the arguments to correctly generate the call sites.  For the interpreted language, it needs metadata describing the argumentation of the methods, whether provided automatically (in this case) or dynamically (see @objc.signature).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2009/11/21/calling-python-from-objective-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyObjC Xcode Templates now in Subversion</title>
		<link>http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/</link>
		<comments>http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 07:51:31 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/</guid>
		<description><![CDATA[Ronald and I realized that the Xcode templates that are included in Leopard didn&#8217;t make it into the PyObjC repository. So, I moved &#8216;em over. You can find them in the PyObjC subversion repository. These aren&#8217;t just templates, though. See the README.txt. As it implies, the project-tool.py script is used to effectively convert between Xcode [...]]]></description>
			<content:encoded><![CDATA[<p>Ronald and I realized that the Xcode templates that are included in Leopard didn&#8217;t make it into the PyObjC repository.</p>
<p>So, I moved &#8216;em over.</p>
<p>You can find them in the <a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2/pyobjc-xcode/">PyObjC subversion repository</a>.</p>
<p>These aren&#8217;t just templates, though.   See the <a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2/pyobjc-xcode/Project%20Templates/README.txt">README.txt</a>.</p>
<p>As it implies, the project-tool.py script is used to effectively convert between Xcode templates and buildable projects.  That is, you can create a project that builds/runs like a regular Xcode project, and then easily turn it into a template with the invocation of a simple command line like this:</p>
<pre>
project-tool.py -k -v --template Cocoa-Python\ Document-based\ Application/CocoaDocApp.xcodeproj/TemplateInfo.plist \
    Cocoa-Python\ Document-based\ Application/ \
    ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/AA\ Testing/Cocoa-Python\ Document-based\ Application
</pre>
<p>Or, specifically:</p>
<pre>./project-tool --help
Usage: project-tool.py [options] <source> <dest>

    Copies tree of templates or projects from <source> to <dest>.
    Before copying, it cleans up <source> by removing various bits of garbage.
    After copying, it transforms <dest> by replacing strings with their Xcode
    template counterparts.

    The reverse flag can be used to reverse this process; turning an Xcode
    template into a working project.

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -v, --verbose         verbose
  -k, --kill-dest       erase </dest><dest> (no warning)
  -r, --reverse         reverse transformation (template -> editable project)
  -w, --working         try to make destination into a working project
  -n, --nib             rewrite NIB files to 10.5 text-only format
  -t TEMPLATEFILE, --template=TEMPLATEFILE
                        path to TemplateInfo.plist that should be used during
                        conversion
</dest></source></dest></source></dest></source></pre>
<p>Nothing remotely Python specific about it.   And, as some have noticed, the PyObjC Cocoa templates leverage the new Interface Builder file format (<a href="http://developer.apple.com/documentation/DeveloperTools/Conceptual/IB_UserGuide/BuildingaNibFile/chapter_4_section_6.html">xib</a>) such that all kinds of substitutions happen in the templated interfaces, too.   As in:  No more <em><strong>MyDocument</strong></em> ever again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Can Ruby, Python and Objective-C Co-exist in a Single Application?</title>
		<link>http://www.friday.com/bbum/2007/11/25/can-ruby-python-an-objective-c-co-exist-in-a-single-application/</link>
		<comments>http://www.friday.com/bbum/2007/11/25/can-ruby-python-an-objective-c-co-exist-in-a-single-application/#comments</comments>
		<pubDate>Sun, 25 Nov 2007 05:55:08 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2007/11/25/can-ruby-python-an-objective-c-co-exist-in-a-single-application/</guid>
		<description><![CDATA[In short, Yes. But not without some pain. You can grab an example of the Python and Ruby bridges working together in a Cocoa application from either this downloadable zip or from this Subversion repository (in case something actually changes). It works. Sort of. Ironically, this likely would have worked better under the pre-BridgeSupport versions [...]]]></description>
			<content:encoded><![CDATA[<p>In short, <a href="http://www.friday.com/misc/PyRu.zip">Yes</a>.  But not without some pain.</p>
<p>You can grab an example of the Python and Ruby bridges working together in a Cocoa application from either this <a href="http://www.friday.com/misc/PyRu.zip">downloadable zip</a> or from <a href="http://svn.red-bean.com/bbum/trunk/hacques/Silly/PyRu/">this Subversion repository</a> (in case something actually changes).</p>
<p>It works.  Sort of.  Ironically, this likely would have worked better under the pre-<a href="http://trac.macosforge.org/projects/BridgeSupport">BridgeSupport</a> versions of <a href="http://rubycocoa.sourceforge.net/HomePage">RubyCocoa</a> and <a href="http://pyobjc.sourceforge.net/">PyObjC</a>.</p>
<p>Specifically, RubyCocoa and PyObjC both assume that nothing else might have loaded the dynamic libraries that are automatically generated by the <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/gen_bridge_metadata.1.html">gen_bridge_metadata</a> script.  So, either bridge will quite happily attempt to load <code>/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation.dylib</code> and then barf mightily when the other bridge has already loaded the same dylib.</p>
<p>The example is rife with silliness related to catching the resulting exceptions and ignoring them.  Worse, the fallout is such that <code>from Foundation import *</code> doesn&#8217;t actually cause the Objective-C classes to be defined within the importing module.</p>
<p>There is a back door &#8212; <code>objc.lookUpClass()</code> &#8212; but this is yet further evidence that, at this time, mixing these two languages in a single Cocoa application is not anything more than a silly hacque (as the SVN repository subdir indicates).</p>
<p>What does it do?</p>
<p>Not much, really.</p>
<ul>
<li>Start with RubyCocoa Application Template (because I can deal with brokeness in Python, I wanted to start with something working in Ruby)</li>
<li>NSApp Delegate written in Obj-C</li>
<li>Finish loading hooks used to bootstrap PyObjC/Python (with gross exception ignoring goofiness related to the dylib)</li>
<li>Bind a table view to an array of dicts where each dict has the key &#8220;name&#8221; leading to a string value bound through array controller.</li>
<li>Array controller bound through app delegate method.</li>
<li>App delegate returns array of dictionaries by calling python based NSObject subclass.</li>
<li>Python based NSObject subclass composes an array of dictionaries (all python) from a combinatio of Python strings and Ruby strings by calling an instance of a Ruby based subclass of NSObject.</li>
</ul>
<p>Very little code.  Lots of moving parts.  Some gears grinding.  Maybe even a gear tooth or four missing.   Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2007/11/25/can-ruby-python-an-objective-c-co-exist-in-a-single-application/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>PyObjC 2.0 Source Available</title>
		<link>http://www.friday.com/bbum/2007/11/01/pyobjc-20-source-available/</link>
		<comments>http://www.friday.com/bbum/2007/11/01/pyobjc-20-source-available/#comments</comments>
		<pubDate>Fri, 02 Nov 2007 03:26:51 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2007/11/01/pyobjc-20-source-available/</guid>
		<description><![CDATA[Ronald comitted the source for PyObjC 2.0 into the public repository. It can be found at PyObjC 2.0 trunk (http://svn.red-bean.com/pyobjc/branches/pyobjc2). The NEWS.txt file is extremely illuminating as there were tons and tons of changes and bug fixes in 2.0. It cannot be emphasized enough; this is a huge release for PyObjC. As big as when [...]]]></description>
			<content:encoded><![CDATA[<p>Ronald comitted the source for PyObjC 2.0 into the public repository.</p>
<p>It can be found at <a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2"> PyObjC 2.0 trunk</a> (<a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2">http://svn.red-bean.com/pyobjc/branches/pyobjc2</a>).</p>
<p>The <a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2/pyobjc-core/NEWS.txt">NEWS.txt</a> file is extremely illuminating as there were tons and tons of changes and bug fixes in 2.0.</p>
<p>It cannot be emphasized enough;  this is a <em>huge</em> release for PyObjC.  As big as when PyObjC first gained subclassing (which wasn&#8217;t until about 7 years into its 14 year history).  Go read the <a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2/pyobjc-core/NEWS.txt">NEWS file</a>;  both major enties on PyObjC 2.0.</p>
<p>Note that libffi on Leopard is fully 64 bit and, thus, PyObjC should be mostly ready for 64 bit, though it was neither built for, nor tested with, 64 bit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2007/11/01/pyobjc-20-source-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyObjC 2.0 (PyObjC in Leopard)</title>
		<link>http://www.friday.com/bbum/2007/10/27/pyobjc-20-pyobjc-in-leopard/</link>
		<comments>http://www.friday.com/bbum/2007/10/27/pyobjc-20-pyobjc-in-leopard/#comments</comments>
		<pubDate>Sat, 27 Oct 2007 16:47:46 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2007/10/27/pyobjc-20-pyobjc-in-leopard/</guid>
		<description><![CDATA[Leopard includes PyObjC 2.0, a huge upgrade over the 1.x series that will be hitting the public repository in the very near future (Ronald&#8217;s time permitting). Both Ronald (who did all the work) and I (sort of) had posted previews of PyObjC 2.0. Now the full magnitude of this release can be publicly discussed. In [...]]]></description>
			<content:encoded><![CDATA[<p>Leopard includes <a href="http://pyobjc.sourceforge.net/">PyObjC</a> 2.0, a huge upgrade over the 1.x series that will be hitting <a href="http://svn.red-bean.com/pyobjc">the public repository</a> in the very near future (Ronald&#8217;s time permitting).</p>
<p>Both <a href="http://ronaldoussoren.blogspot.com/2007/07/sneak-preview-of-pyobjc-20.html">Ronald (who did all the work)</a> and <a href="http://www.friday.com/bbum/2007/07/20/preview-of-pyobjc-20/">I (sort of)</a> had posted previews of PyObjC 2.0.  Now the full magnitude of this release can be publicly discussed.</p>
<p>In particular, <a href="http://ronaldoussoren.blogspot.com/2007/07/sneak-preview-of-pyobjc-20.html">Ronald&#8217;s post</a> gives an excellent overview of the new features and capabilities of PyObjC.</p>
<p>There is a theme: &#8220;greatly tighten the integration with Mac OS X in a more consistent and less special-cased fashion&#8221;.</p>
<p>Read on for details:<br />
<span id="more-919"></span><br />
To that particular end, PyObjC 2.0 &#8212; like recent releases of <a href="http://rubycocoa.sourceforge.net/">RubyCocoa</a> &#8212; embraces the metadata generated by <a href="http://trac.macosforge.org/projects/BridgeSupport">BridgeSupport</a>.   BridgeSupport allows a machine-readable description of APIs &#8212; be they C or Objective-C &#8212; in XML, with support for 32 vs. 64 bit differences.   PyObjC and RubyCocoa use the BridgeSupport metadata o make calls from the interpreter into the native ABI on the system.   Succinctly;  BridgeSupport allows for data driven calls through to APIs that were previously special cased either per call site or per bridge implementation.</p>
<p>BridgeSupport is included with Leopard, including documentation.   See the <a href="x-man-page:gen_bridge_metadata">gen_bridge_metadata</a> and <a href="x-man-BridgeSupport">BridgeSupport</a> man pages.   As well, a full-text search in Xcode&#8217;s documentation viewer reveals another chunk of documentation.</p>
<p>At the other end, Leopard also includes a vastly improved version of <a href="http://sources.redhat.com/libffi/">libffi</a>.  Beyond a number of bug fixes and actually having a man page now, libffi also correctly supports both 64 bit ABIs available in Leopard;  ppc64 and x86_64.</p>
<p><em>Specifically, PyObjC and RubyCocoa use the BridgeSupport generated metadata to construct native calls via the FFI API.<br />
</em></p>
<p>Leopard provides metadata for most of the frameworks and CF-or-higher level APIs on the system.  Not all;  some APIs can&#8217;t be expressed via the metadata yet (C++, for example).</p>
<p>The list is quite long:</p>
<ul>
<li>libSystem</li>
<li>AddressBook</li>
<li>AppKit</li>
<li>AppleScriptKit</li>
<li>ApplicationServices</li>
<li>ApplicationServices/CoreGraphics</li>
<li>ApplicationServices/CoreText</li>
<li>ApplicationServices/ImageIO</li>
<li>ApplicationServices/SpeechSynthesis</li>
<li>Automator</li>
<li>CalendarStore</li>
<li>SpeechRecognition</li>
<li>Cocoa</li>
<li>Collaboration</li>
<li>CoreAudio</li>
<li>CoreAudioKit</li>
<li>CoreData</li>
<li>CoreFoundation</li>
<li>CarbonCore</li>
<li>DictionaryServices</li>
<li>CoreVideo</li>
<li>DVDPlayback</li>
<li>DirectoryService</li>
<li>DiscRecording</li>
<li>DiscRecordingUI</li>
<li>ExceptionHandling</li>
<li>Foundation</li>
<li>ICADevices</li>
<li>IOBluetooth</li>
<li>IOBluetoothUI</li>
<li>InputMethodKit</li>
<li>InstallerPlugins</li>
<li>InstantMessage</li>
<li>JavaScriptCore</li>
<li>LatentSemanticMapping</li>
<li>OSAKit</li>
<li>OpenGL</li>
<li>PreferencePanes</li>
<li>PubSub</li>
<li>QTKit</li>
<li>ImageKit</li>
<li>PDFKit</li>
<li>QuartzComposer</li>
<li>Quartz</li>
<li>QuartzCore</li>
<li>ScreenSaver</li>
<li>ScriptingBridge</li>
<li>SecurityFoundation</li>
<li>SecurityInterface</li>
<li>SyncServices</li>
<li>SystemConfiguration</li>
<li>WebKit</li>
<li>XgridFoundation</li>
<li>WhitePages</li>
</ul>
<p>Not all of these APIs are available directly in PyObjC. Yet.  Some require a touch of glue.  If &#8220;import FrameWork&#8221; doesn&#8217;t work, glue will be needed.  More on the glue in a later post.</p>
<p>Both the metadata listed above and the tools to generate the metadata are provided without requiring the dev tools to be installed.   Dev tools are necessary if metadata generation also creates a dylib that contains any bits &#8212; static inline functions, for example &#8212; that cannot be expressed purely in XML.</p>
<p>And, of course, it is quite straightforward to generate bridge metadata for your own Objective-C and C APIs.   It is just a matter of running the <code>gen_bridge_metadata</code> utility against your APIs.   Exceptions in the form of XML that overrides the automatically generated XML can be provided, too.</p>
<p>In essence, Apple is taking a bit of a different approach to embracing and supporting scripting languages to develop native applications.</p>
<p>Instead of trying to crowbar the scripting language&#8217;s syntax on top of whatever VM-du-jour happens to be running on the platform, BridgeSupport &#8212; and, by integration, Leopard &#8212; provides all of the metadata necessary to allow the native scripting language to be used to create native applications through a bridge between the two.   Given that BridgeSupport works just fine on Tiger, this isn&#8217;t something limited to Leopard.</p>
<p>The metadata is intended to be a resource for use beyond bridging.  Most frameworks on the system provide two chunks of XML BridgeSupport metadata;  succinct and full.   The succinct version contains all of the metadata <em>not</em> provided by the Objective-C runtime (which provides about 80% of what is necessary to do full fidelity calls in / out of Objective-C via libffi).   The full version contains  just that, the full metadata required to describe the APIs of the framework, including all the bits that could be gleaned at runtime.</p>
<p>Already, the BridgeSupport API metadata is used for more than just bridging languages.  For example, Xcode offers Objective-C method name completion in standalone Python and Ruby source files &#8212; no project necessary &#8212; by leveraging the BridgeSupport metadata!</p>
<p>I am looking forward to seeing the imaginative ways with which developers leverage the BridgeSupport metadata.   Certainly, there is more work to be done, but it should provide a very strong foundation for innovation as it is now!</p>
<p>Once PyObjC 2.0 move over to the public repository, I fully expect that development on 2.0 will continue beyond what ships in Leopard.   As a consumer of PyObjC, it will be up to you to decide whether you want to stick with what is in Leopard or track PyObjC development.</p>
<p>For most folks, what is in Leopard will be just fine &#8212; it works great for building Cocoa applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2007/10/27/pyobjc-20-pyobjc-in-leopard/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Preview of PyObjC 2.0</title>
		<link>http://www.friday.com/bbum/2007/07/20/preview-of-pyobjc-20/</link>
		<comments>http://www.friday.com/bbum/2007/07/20/preview-of-pyobjc-20/#comments</comments>
		<pubDate>Fri, 20 Jul 2007 06:23:15 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2007/07/20/preview-of-pyobjc-20/</guid>
		<description><![CDATA[While it appears that PyObjC development has stagnated, nothing could be further from the truth. Ronald posted a very nice overview of the tasty goodness in PyObjC 2.0. He has been very very busy. Yes, it fully leverages the metadata generated by the BridgeSupport project. Via BridgeSupport, PyObjC &#8212; and RubyCocoa, and anything else leveraging [...]]]></description>
			<content:encoded><![CDATA[<p>While it appears that <a href="http://pyobjc.sourceforge.net/">PyObjC</a> development has stagnated, nothing could be further from the truth.</p>
<p>Ronald posted a very nice overview of the <a href="http://ronaldoussoren.blogspot.com/2007/07/sneak-preview-of-pyobjc-20.html">tasty goodness in PyObjC 2.0</a>.   He has been very very busy.</p>
<p>Yes, it fully leverages the metadata generated by the <a href="http://trac.macosforge.org/projects/BridgeSupport">BridgeSupport</a> project.   Via BridgeSupport, PyObjC &#8212; and <a href="http://rubycocoa.sourceforge.net/HomePage">RubyCocoa</a>, and anything else leveraging BridgeSupport &#8212; has enough metadata to bridge to just about any C or Objective-C API.   The goal of BridgeSupport is to provide a machine readable description of system APIs with full fidelity;  something that the Objective-C runtime metadata does not provide (including, for example, information about straight C functions).</p>
<p>Ronald:  <b>Thank you.</b>  12 years is a long time for any open source project to remain active and the last year, largely through Ronald&#8217;s contributions, has proven to be one of the most vibrant years of development in the project&#8217;s history!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2007/07/20/preview-of-pyobjc-20/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AAPL &gt; DELL</title>
		<link>http://www.friday.com/bbum/2006/05/02/aapl-dell/</link>
		<comments>http://www.friday.com/bbum/2006/05/02/aapl-dell/#comments</comments>
		<pubDate>Tue, 02 May 2006 17:50:46 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2006/05/02/aapl-dell/</guid>
		<description><![CDATA[Apple has surpassed Dell in the market cap department. This happened earlier in the year and then Apple&#8217;s stock got nailed. Hopefully, that won&#8217;t be the pattern this time around. Ronald Oussoren &#8212; of PyObjC and Universal Python fame (amongst other things) &#8212; is in town and will be joining us for Korean food and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.google.com/finance?q=AAPL">Apple</a> has surpassed <a href="http://www.google.com/finance?q=DELL">Dell</a> in the market cap department.  This happened earlier in the year and then Apple&#8217;s stock got nailed.</p>
<p>Hopefully, that won&#8217;t be the pattern this time around.</p>
<p>Ronald Oussoren &#8212; of <a href="http://pyobjc.sourceforge.net/">PyObjC</a> and <a href="http://bob.pythonmac.org/archives/2006/04/10/python-and-universal-binaries-on-mac-os-x/">Universal Python</a> fame (amongst other things) &#8212; is in town and will be joining us for Korean food and Bowling this evening.  Korean food starts at 7:30pm at Fusion Korea next to Homestead Lanes (though we don&#8217;t bowl there &#8212; long story).</p>
<p><center><br />
<img src="http://us.i1.yimg.com/us.yimg.com/i/us/mp/gr/mplogo.gif" width="99" height="13" border=0 align=middle alt="[ Yahoo! Maps ]"/><br />
<a href="http://us.rd.yahoo.com/maps/extmap;_ylt=Ar2XAw7rHMFbWZly0n5RlZNkDLMF/*-http://maps.yahoo.com/maps_result?addr=20956+Homestead+Rd+Ste+A1&#038;csz=Cupertino%2C+CA+95014-0310&#038;state=CA&#038;uzip=95014&#038;ds=n&#038;name=&#038;desc=&#038;lat=37.3375&#038;lon=-122.040383&#038;mlt=37.3375&#038;mln=-122.040383&#038;zoomin=no&#038;BFKey=&#038;mag=2"><br />
Map of Fusion Korea:<br />
20956 Homestead Rd Ste A1<br />Cupertino, CA 95014-0310<br /></a></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2006/05/02/aapl-dell/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Universal Python Build</title>
		<link>http://www.friday.com/bbum/2006/04/10/universal-python-build/</link>
		<comments>http://www.friday.com/bbum/2006/04/10/universal-python-build/#comments</comments>
		<pubDate>Tue, 11 Apr 2006 04:03:42 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2006/04/10/universal-python-build/</guid>
		<description><![CDATA[Bob Ippolito and Ronald Oussoren have been working on a branch of Python 2.4 with the intention of creating a universal build of Python. They have done that and more. A lot more. In the process, many other aspects of Python on Mac OS X have been fixed or optimized. Furthermore, the Python build now [...]]]></description>
			<content:encoded><![CDATA[<p>Bob Ippolito and Ronald Oussoren have been working on a branch of Python 2.4 with the intention of creating a universal build of Python.</p>
<p><a href="http://bob.pythonmac.org/archives/2006/04/10/python-and-universal-binaries-on-mac-os-x/">They have done that and more</a>.  A lot more.  In the process, many other aspects of Python on Mac OS X have been fixed or optimized.  Furthermore, the Python build now uses SDKs as a part of the build.  This lays the framework for being able to do development on one version of the OS while targeting older versions with <i>Python</i>.  Very nice.</p>
<p>This is one of the areas of the world of universal binaries that few people really understand.</p>
<p><i>Building a <b>correct</b> universal binary of most open source projects is exceedingly hard.</i></p>
<p>Simply passing <code>CFLAGS=-arch i386 -arch ppc</code> will generally <i>not</i> yield a correct binary.  Worse, if the project uses autoconf, you can rest assured that the result of <code>./configure ; sudo make install</code> will only yield a correct result for the architecture the build is created on.  While autoconf can support cross-compilation, very few developers using autoconf will jump through the hoops necessary to do so.</p>
<p>And that is really what this boils down to.  Cross compilation is hard to get right.  Xcode makes building universal binaries easy because the entire high level Mac OS X development model and all of the predecessor technology has been focused on cross-compilation for well over a decade.</p>
<p>If you are planning on developing or maintaining a body of source targeted to Mac OS X that cannot use the Xcode native build system &#8212; and there are certainly many reasons to do so &#8212; I would highly recommend that you go have a close look at Ronald&#8217;s and Bob&#8217;s work.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2006/04/10/universal-python-build/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tracing Python Execution</title>
		<link>http://www.friday.com/bbum/2005/10/27/tracing-python-execution/</link>
		<comments>http://www.friday.com/bbum/2005/10/27/tracing-python-execution/#comments</comments>
		<pubDate>Fri, 28 Oct 2005 01:54:41 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=538</guid>
		<description><![CDATA[While working with Twisted and Nevow, I ran into a situation where something terribly nasty was happening well below any code I had written. Basically, I was faced with the classic high level development problem of &#8220;something I did long ago broke something deep within several layers of large scale systems I did not write&#8221;. [...]]]></description>
			<content:encoded><![CDATA[<p>While working with <a href="http://twistedmatrix.com/">Twisted</a> and <a href="http://divmod.org/projects/nevow">Nevow</a>, I ran into a situation where something terribly nasty was happening well below any code I had written.  Basically,  I was faced with the classic high level development problem of &#8220;something I did long ago broke something deep within several layers of large scale systems I did not write&#8221;.</p>
<p>In these situations, a debugger does little good because there is little clue as to where things went awry.   What I really needed was a way to trace execution.</p>
<p>It turns out that Python has excellent hooks for doing exactly that.</p>
<p>Add the following to any random hunk o&#8217; code:</p>
<pre>
import sys
import linecache
import inspect

def traceit(frame, event, arg):
    if event == 'line':
        lineno = frame.f_lineno
        if '__file__' in frame.f_globals:
            filename = frame.f_globals['__file__']
            if (filename.endswith('.pyc') or
                filename.endswith('.pyo')):
                filename = filename[:-1]
            name = frame.f_globals['__name__']
            line = linecache.getline(filename, lineno)
        else:
            name = '[unknown]'
            try:
                src = inspect.getsourcelines(frame)
                line = src[lineno]
            except IOError:
                line = 'Unknown code named [%s].  VM instruction #%d' % \
                    (frame.f_code.co_name, frame.f_lasti)
        print '%s:%s: %s' % (name, lineno, line.rstrip())
    return traceit
</pre>
<p>Then, to turn it on, call sys.settrace().  You can easily toggle the trace functionality, thus reducing the tracing to a very limited portion of the overall execution.   This prevents one from drowning in data.</p>
<pre>
sys.settrace(traceit)
</pre>
<p>Note that the function has a frame object as an argument.  That frame object allows for extremely deep introspection of the execution state, including variable state and just about anything else you would like to find out about the underlying virtual machine.</p>
<p>The original code was cribbed from <a href="http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html">the dalke scientific site</a>.   That <a href="http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html">article</a> has an awesome explanation of the details of tracing.  I just added some error checking and fallback code in the case where the original file/source cannot be determined.  This enables the tracing functionality to work seamlessly within the context of Twisted.</p>
<p>It has already saved me a ton of time and I&#8217;m about to throw this permanently into my local Python library.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2005/10/27/tracing-python-execution/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Neat PyObjC Trick</title>
		<link>http://www.friday.com/bbum/2005/10/19/neat-pyobjc-trick/</link>
		<comments>http://www.friday.com/bbum/2005/10/19/neat-pyobjc-trick/#comments</comments>
		<pubDate>Wed, 19 Oct 2005 15:11:33 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Core Data]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=537</guid>
		<description><![CDATA[I demoed the latest build of PyObjC at the recent CocoaHeads meeting in Cupertino. The demo concluded with a &#8220;show all [most, really] the tricks at once&#8221; sequence. How py2app, a part of PyObjC, will automatically create an installer package from a standard Python package Injecting a live Python interpreter into a running application Introspecting [...]]]></description>
			<content:encoded><![CDATA[<p>I demoed the latest build of <a href="http://pyobjc.sf.net/">PyObjC</a> at the recent <a href="http://www.cocoaheads.org/">CocoaHeads</a> meeting in Cupertino.</p>
<p>The demo concluded with a &#8220;show all [most, really] the tricks at once&#8221; sequence.</p>
<ul>
<li>How py2app, a part of PyObjC, will automatically create an installer package from a standard Python package</li>
<li>Injecting a live Python interpreter into a running application</li>
<li>Introspecting the application</li>
<li>Interacting with Core Data, including dealing with ** style parameters</li>
<li>Modifying a managed object and having KVO automatically fire on assignment</li>
</ul>
<p>First, grab the top-of-tree source from the pyobjc repository:</p>
<pre>
svn co http://svn.red-bean.com/pyobjc/trunk/pyobjc/
</pre>
<p>Alternatively, you can mount that URL in the finder (click cancel on all the bloody attempts to write .DS_Store files) and cp -r the source to somewhere from the Terminal.</p>
<p>Then:</p>
<pre>
cd pyobjc
python setup.py bdist_mpkg --open
</pre>
<p>That will build PyObjC and open an Installer package that contains the runtime, documentation, examples, and Xcode templates.</p>
<p>Next, grab the OutlineEdit examples from <i>/Developer/Examples/CoreData/</i> and run it.</p>
<p>Now, from the PyObjC source directory:<br />
<span id="more-537"></span></p>
<pre>
cd Examples/Inject/InjectInterpreter
ps aux | grep OutlineEdit
... note the PID ...
python test.py PID
</pre>
<p>The InjectInterpreter will be built and, shortly, you will see a Window pop up in OutlineEdit containing a Python interpreter.</p>
<p>Click on OutlineEdit and add some new Notes in the Untitled document window.  Quantity and structure don&#8217;t matter.</p>
<p>Now, click on the interpreter window and do:</p>
<pre>
from AppKit import *
from objc import *
</pre>
<p>At this point, we now have the PyObjC bridge imported into the Python interpreter that is running within the Main Event Loop of OutlineEdit.   With that in place, we can now interact with the Cocoa infrastructure to interrogate and manipulate the application.   Since this is a Core Data application, we can &#8212; of course &#8212; interact with all the Core Data goodness within the document.</p>
<p>First, we need to get a hold of all that Core Data goodness:</p>
<pre>
d = NSDocumentController.sharedDocumentController().documents()[0]
mom = d.managedObjectModel()
moc = d.managedObjectContext()
noteEntity = mom.entitiesByName()['Note']
fr = NSFetchRequest.new()
fr.setEntity_(noteEntity)
</pre>
<p>Now, grab one of the Note objedcts:</p>
<pre>
notes, error = moc.executeFetchRequest_error_(fr)
note = notes[0]
</pre>
<p>And manipulate:</p>
<pre>
note.contents = u'Hello, world!'
</pre>
<p>Note that as soon as you hit return, the UI updates.  This happens because PyObjC is smart enough to trigger the KVO/KVC notifications upon assignment to an attribute of an NSObject subclass.</p>
<p>And, of course, if you screw up the state of the document too badly:</p>
<pre>
moc.undo()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2005/10/19/neat-pyobjc-trick/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

