Hacking PyObjC (Bob Ippolito).notes

Wednesday, March 23, 2005

TITLE OF PAPER: Hacking PyObjC
URL OF PRESENTATION: _URL_of_powerpoint_presentation_
PRESENTED BY: Bob Ippolito
REPRESENTING:

CONFERENCE: PyCon 2005
DATE: March 23, 2005
LOCATION: 307

--------------------------------------------------------------------------
REAL-TIME NOTES / ANNOTATIONS OF THE PAPER:
{If you've contributed, add your name, e-mail & URL at the bottom}

Classes have flat namespace
    objc contains >1200 classes, most written by Apple
    look up by name: objc.lookUpClass()
    
Categories
    Add functionality to a class *after* it was created
    Add, replace, observe, patch functionality
    Similar to method swizzling but different (don't have access to the original implementation)
    Example: add Python gmtime() method to Foundation's NSDate
        Adds retroactively to existing objects, too
        
Protocols
    Declares formal interfaces w/o inheritance
    Obj-C also uses informal protocols (duck typing), but occasionally need formal
        Use conformsToProtocol_() method to explicitly check
    Protocols have a single namespace that is distinct from the class namespace
    NSCoding is equivalent to Pickle
    (prepending) Underscores in variable names are reserved by Apple, don't use them
    Declare conformance by inheriting from the protocol
    ObjC 'for consenting adults' - you can claim to do things and don't actually do them, much like Python
    Possible to create new protocol in Python: objc.formal_protocol()
        Painful to do, and not often (ever) needed

Selectors
    Converting ObjC to Python: change colons to underscores
    Assumes all the values are objects
    Knows to "return" void if Python code has no return statement
    Implementing non-default selectors:
        (this is where decorators would be used, but we don't currently)
        need to know arcane typecodes (but only in this case)
    
Wrapping non-standard frameworks
    (third-party or new Apple ones)
    
    Can be done in Python, pretty easy

Write Plugins in PyObjC
    Written just like frameworks, but with different linking
    Python is not great at this due to Python's global state
    Usually it's good enough, as long as you have just one plugin
    Useful for
        Services (bad idea due to global state) DON'T DO THIS!!!! (or rather use        
            process-based API)
        Input Managers (ditto)
        Screen Savers
        Interface Builder palettes (create your own widgets)
        extend existing cocoa applications
    To build a plugin, set the custom key (NSPrincipalClass) in the plist
        No need to explicitly export classes any more

objc.inject
    Loading code into running applications
    Think gdb.attach, e.g. embed Python interpreter
    Module-level code does not run in the main thread
        AppKit does not like this
        Need to write a function to make sure the rest of the code runs on the main thread
        crash prone
    Uses Mach create thread API, creates random thread in another process and loads a plugin into it
    
[example of opening class browser inside Preview using objc.inject]
[example of injecting Python interpreter into Preview]
    Bob 0wnzors Preview
    .. Python takes over the world.
    can use AppKit.NSApp() apparently, instead of NSApplication.sharedApplication()
        (F-Script doesn't let you do this)
    pyobjc 1.3 /Developer/Python/PyObjC/Examples/Inject/InjectInterpreter
       run python test.py <pid> to inject interpreter

Major issue to integrating GNUstep - no public API for doing things like adding methods

You can inject code (a category) into a method in another process
   IDNSnitch example in PyObjC 1.3 - works around IDN issues in Safari

You can use method swizzling to wrap an existing method (covered in IDNSnitch as well)

--------------------------------------------------------------------------
REFERENCES: {as documents / sites are referenced add them below}
http://pyobjc.sourceforge.net/ ["official" releases]
http://svn.red-bean.com/pyobjc/trunk/pyobjc/ [live on the edge]
http://bob.pythonmac.org/ [Bob's blog]
/Developer/Python/PyObjC/Documentation [on your hard disk...]
/Developer/Python/PyObjC/Examples      [...after you install PyObj]
http://pythonmac.org/wiki
http://developer.apple.com/
http://cocoadev.com/ [wiki for Cocoa stuff]
/Developer/Examples/AppKit
cocoa-dev@lists.apple.com
AppKiDo - documentation search application

--------------------------------------------------------------------------
QUOTES:
"I can do useful things, like make it crash..."  Bob


--------------------------------------------------------------------------
CONTRIBUTORS: {add your name, e-mail address and URL below}
Russell Finn <rsf@sprucehill.com> http://www.sprucehill.com/rsf/blog
Abhay Saxena <ark3@email.com>
Ted Leung <twl@sauria.com>
Nicholas Riley <nriley@sabi.net> http://njr.pycs.net/
Linden Wright <lwright@mac.com>

--------------------------------------------------------------------------
E-MAIL BOUNCEBACK: {add your e-mail address separated by commas }



--------------------------------------------------------------------------
NOTES ON / KEY TO THIS TEMPLATE:
A headline (like a field in a database) will be CAPITALISED
    This differentiates from the text that follows
A variable that you can change will be surrounded by _underscores_
    Spaces in variables are also replaced with under_scores
    This allows people to select the whole variable with a simple double-click
A tool-tip is lower case and surrounded by {curly brackets / parentheses}
    These supply helpful contextual information.

--------------------------------------------------------------------------
Copyright shared between all the participants unless otherwise stated...