An overview of the relevant changes in new, and older, releases.
TODO: this framework uses lots of macros (such as STAssertEquals), these have not yet been wrapped/converted.
objc.RegisterCFSignature used to register CFTypeRef-like
signatures with the runtime.PyObjCTools.Conversion functions now support all property list
types with the following conversions:New toPythonDecimal, fromPythonDecimal functions which convert
between NSDecimalNumber and decimal.Decimal using an intermediate string.
New serializePropertyList and deserializePropertyList functions
which serialize (Objective-C) property lists to and from NSData.
OC_PythonObject, the proxy for Python objects that do not have
an Objective-C superclass and are not otherwise special-cased, now
act slightly more like typical Objective-C objects (supporting
-isEqual:, -hash, and -compare:). This allows them
to work with Key-Value Coding if they are contained by an Objective-C
object, among other things.
@objc.signature('i@:if')
def methodWithX_andY_(self, x, y):
return 0
PyObjCTools.KeyValueCoding.getKeyPath now supports all of the
Array Operators supported by Mac OS X 10.4.objc.protocolsForProcess() enumerates over all mach
headers and returns all of the protocols defined in the expected
place. This fixes the scenario where an application uses a
protocol but does not define any classes that
conform to that protocol (i.e. to check plugin conformity).
Previously it was not possible to reach these protocols simply by
walking over all of the classes.objc.NULL, may now be passed in the place
of 'in' and 'inout' arguments. This tells the bridge to pass
a NULL pointer to the Objective-C method, instead of a pointer
to the value. The return value will still be a tuple of the
expected size.AppleScriptKitAutomatorCoreDataDiscRecordingDiscRecordingUIOSAKitQuartzQTKitSyncServicesXgridFoundationDocumentation and tests not yet written.
OutlineEditor example in Examples/CoreData,
it is a Python version of the identically named Apple example.list-like and dict-like
objects: __reversed__, reverse, pop,
remove, fromkeys.OC_PythonDictionary and OC_PythonArray now return
NSNull to Objective-C callers as appropriate.WebKitInterpreter example in Examples/Plugins.
Uses the new WebKit Cocoa plugin API available in Safari 1.3
and later to embed a PyInterpreter in the browser.CFBundleRef reference counting bug in
Foundation._Foundation. The symptom of this is usually
a crashing application after having loaded a PyObjC-based
plugin into an otherwise Objective-C app.PyObjCTools.AppHelper functions: callAfter and
callLater, conveniences for calling Python functions on
the main thread as soon as possible, or after a delay.threadedselectreactor
instead of cfreactor. cfreactor is deprecated.
Needs Twisted newer than 2.0 (svn r13575 or later).objc.inject now injects on main thread by default,
and takes an optional third useMainThread argument
to change this behavior. This is a complete rewrite
which should be correct, stable, Tiger compatible,
and synchronized with mach_* 1.1.NSAutoreleasePool category hack that has
been deprecated for quite some time.objc.removeAutoreleasePool function that will remove
PyObjC's global NSAutoreleasePool, which may be useful
for plugins.NSBundle hack that caused a NULL
pointer dereference if looking up a non-existent class using
NSBundle API.OC_PythonUnicode and OC_PythonString classes that
preserve the identity of str and unicode objects across
the bridge. The bridge for str now uses the default
encoding of NSString, rather than sys.getdefaultencoding()
from Python. For Mac OS X, this is typically MacRoman. The reason
for this is that not all Python str instances could cross the
bridge at all previously. objc.setStrBridgeEnabled(False) will
still trigger warnings, if you are attempting to track down an
encoding bug. However, the symptoms of the bug will be incorrectly
encoded text, not an exception.InjectBrowser example in Examples/Inject that demonstrates
injection of the ClassBrowser example into another application using
objc.inject.NSData and NSMutableData instances now support the Python buffer
protocol.NSData instances now support a convenience API that allow them to
act like a buffer instance for str() and slicing.buffer and
array.array (but not str or unicode) are now bridged as
NSData subclasses.objc.pyobjc_id function that returns a the id of the underlying
NSObject as an integer. (Python wrapper objects are often made on the
fly, meaning id(obj) is not constant during the lifetime of the
object.)Exceptions: NSString and NSNumber do not have unique proxies. These
types are converted to subclasses of Python types as appropriate, so they
can not have unique proxies. The identity of the original Objective-C
object is maintained by these subclasses, but there may be many Python
"value proxies" for a single Objective-C object.
Any Python object that is proxied using the __pyobjc_object__
interface will only get a unique proxy if the __pyobjc_object__
method implements that feature.
objc.protocolsForClass function that returns a list of protocols
that the class directly claims to conform to.
class MyLockingClass(NSObject, objc.protocolNamed('NSLocking')):
# implementation
pass
It is also possible to define new protocols:
MyProtocol = objc.formal_protocol("MyProtocol", None, [
selector(None, selector='mymethod', signature='v@:'),
])
All formal protocols are instances of objc.formal_protocol.
kvc class that allows
Pythonic Key-Value Coding.__getitem__ is mapped to valueForKeyPath:__setitem__ is mapped to setValue:forKeyPath:__getattr__ is mapped to valueForKey:__setattr__ is mapped to setValue:forKey:The kvc class uses __pyobjc_object__, so it may cross the bridge
as the wrapped object.
NSNumber instances are bridged to a float, long, or int
subclass that uses __pyobjc_object__.
NSDecimal is converted to NSDecimalNumber when used as an object,
NSDecimalNumber is not bridged to NSDecimal because the latter is
a mutable type.__pyobjc_object__
attribute to get a PyObjC object from a Python object.objc.inject to load code into a target process,
and override the implementation of an existing method but still
call back into the original implementation (method swizzling).objc.IMP should do the right thing now. This type is returned
by +[NSObject methodForSelector:] and
+[NSObject instanceMethodForSelector:]NSArrayController to implement the NSTableView
delegate drag and drop protocol, including copying of objects between
documents and accepting URL drops from other applications. Also
demonstrates re-ordering of the content array. Originally from
"Cocoa Bindings Examples and Hints", converted to PyObjC by u.fiedler.NSArrayController to implement filtering
of a NSTableView. Also demonstrates the use of indexed accessors.
Originally from "Cocoa Bindings Examples and Hints", converted to PyObjC
by u.fiedler.NSObject, unless they implement a custom
willChangeValueForKey:, didChangeValueForKey:, or
__useKVO__ is not True. This allows self.foo = 1 to
automatically trigger notifications. This works in all cases,
whether foo is a property, ivar, or just in the
__dict__.objc.inject() function for Mac OS X 10.3 and later,
allows an arbitrary bundle to be loaded into another process
using mach_inject.objc.classAddMethods now recognizes and supports
classmethods.NSNumber bridge has been removed, now you will get
NSNumber instances across the bridge instead of a
Python representation.PyObjCTools.AppHelper.runEventLoop() will now bring your
application to the front at startup when using pdb
mode for convenience.objc.loadBundle() no longer filters the class list. This
solves a few potential issues and shaves off about 1/3rd of
the overhead of python -c "import AppKit".PyObjCTools.AppHelper.runEventLoop() no longer breaks on
pure Objective-C exceptions. Most exceptions of this variety
are more like warnings, and there is nothing that can be done
them anyway.PyObjCTools.AppHelper.runEventLoop() now installs the
interrupt handler and verbose exception logging when using pdb,
either explicitly or by the USE_PDB environment variable.NSString/unicode
bridge when Py_UNICODE_SIZE is 2. This is the default
setting for Python.__bundle_hack__ is no longer necessary, py2app now sets
a different environment variable to the current plugin during
execution, and a hack is installed to NSBundle so that classes
may respond to requests for their bundle with the +bundleForClass
method. The class builder adds a default implementation of this to
Python classes if this environment variable is set.objc.currentBundle(), which is equivalent to
NSBundle.mainBundle() except after loading a plug-in.
Makes it easier to load nib files.PyObjCTools.NibClassBuilder.extractClasses() now uses
objc.currentBundle() instead of NSBundle.mainBundle(). This
makes plugins less of a hassle to develop and allows identical code
to be used for application or plugin development.objc.registerPlugin() and objc.pluginBundle() are now deprecated
as they are no longer useful.copyWithZone:
without setting __slots__ to ().dealloc. It is still possible to
define __del__.retain and
release. Note it almost never a good idea to do this (even when you're
programming in Objective-C and much more so in Python).poseAsClass: can be used, although it is not very useful in python, use
categories instead.A major issue with poseAsClass: is that existing references to the old
version of the class won't be changed to point to the new class.
objc.listInstanceVariables(aClassOrInstance),
objc.getInstanceVariable(obj, name) and
objc.setInstanceVariable(obj, name, value [, updateRefCount]).The last argument of setInstanceVariable is required when the instance
variable is an object. If it is true the bridge will update reference counts,
otherwise it won't.
NSZone*) now have the same
interface and share a single implementation. This decreases code-size and
makes it easier to add new wrappers. A new feature is a __typestr__
attribute on the type object, this contains the encoded Objective-C type
of the pointer.A function for creating new wrappers is exposed to python, as
objc.createOpaquePointerType(name, typestr, doc). The same function is
also exposed in the C-API.
__typestr__ attribute on their type.
This attribute contains the encoded Objective-C type of the struct.The default __init__ for struct-wrappers now initializes fields with an
appropriate default value, instead of None.
New wrappers can now be created from Python using the function
objc.createStructType(name, typestr, fieldnames, doc). The same
function is also exposed in the C API (and has been for a while).
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).reload on modules containing Objective-C
classes.objc.loadBundle now returns bundle we just loaded.objc.loadBundleVariables and objc.loadBundleFunctions,
two functions for reading global variables and functions from a bundle.
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.__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.__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.OC_PythonObject. See
objc._bridges. This is how the str -> unicode -> NSString
bridge with optional warnings is implemented.OC_PythonObject.
See objc._bridges. This is how the Carbon.File.FSRef
<-> '{FSRef=[80c]}' structure bridge is implemented._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.This makes it possible to use at Distributed Objects, although this feature has not received much testing
You can now select a new python file in the 'add file...' dialog in Xcode
class MyClass (NSObject):
def setSomething_(self, value):
pass
setSomething_ = objc.accessor(setSomething_)
def something(self):
return "something!"
something = objc.accessor(something)
It is not necessary to use objc.accessor when overriding an existing
accessor method.
This means you can now access the x-coordinate of a point as aPoint.x,
accessing aPoint[0] is still supported for compatibility with older
versions of PyObjC.
It is still allowed to use tuples, or other sequences, to represent Objective-C structs.
NOTE: This has two side-effects that may require changes in your programs: the values of the types mentioned above are no longer immutable and cannot be used as keys in dicts or elements in sets. Another side-effect is that a pickle containing these values created using this version of PyObjC cannot be unpickled on older versions of PyObjC.
The same is true for defining methods, if you define a method raise__ in
a subclass of NSObject it will registered with the runtime as raise.
NOTE: Currently only class and raise are treated like this, because
those are the only Python keywords that are actually used as Objective-C
method names.
instanceMethodForSelector: and
methodForSelector:.
This support is not 100% stable, and might change in the future.NSKeyValueCoding, the Jaguar version is still
supported.updateNSString of objc.pyobjc_unicode is deprecated, use
create a new unicode object using unicode(mutableStringInstance) instead.Shows how to use OpenGL with PyObjC
Shows how to write a screensaver in Python. Requires a framework install of Python (that is, MacOS X 10.3 or MacPython 2.3 on MacOS X 10.2).
Shows how to integrate Twisted (1.1 or later) with Cocoa, it is a refactor of the WebServicesTool example that is made much simpler by using Twisted.
Shows how to integrate Twisted (1.1 or later) with Cocoa, it is a refactor of the WebServicesTool example that is made much simpler by using Twisted as it does not need threads. This one also uses NSController and therefore requires MacOS X 10.3.
PyObjCTools.KeyValueCoding provides a python interface that makes it
possible to use key-value coding with python objects as well as
Objective-C objects. Key-Value Coding also works as one would expect with
Python objects when accessing them from Objective-C (both for plain Python
objects and Python/Objective-C hybrid objects).description method. This method is not called for unitialized objects,
because that might crash the interpreter; we use a default implementation
in that case.This is a backward incompatible change, but there are not many of such methods.
objc module. The most significant of these is the change from
recycle_autorelease_pool to recycleAutoreleasePool. The other
changed names are internal to the bridge and should not be used in other
code.Two new tutorials were added: 'Adding Python code to an existing ObjC application' and 'Understanding existing PyObjC examples'. The former explains how you can use Python to add new functionality to an already existing Objective-C application, the latter explains how to understand PyObjC programs written by other people.
Three examples were added: DotView, ClassBrowser and PythonBrowser, respectively showing the use of a custom NSView, NSBrowser and NSOutlineView. PythonBrowser is reusable, making it trivial to add an object browser to your application.
It is now possible to build PyObjC on MacOS X 10.1, with full access to the Cocoa API's on that platform.
Note: The port to MacOS X 10.1 is not as well supported as the 10.2 port. The developers do not have full-time access to a MacOS X 10.1 system.
If you build PyObjC from source you will have to build on a system that has the WebKit SDK installed to make use of this. Note that the additional functionality will only be usuable on systems that have Safari 1.0 installed, however as long as you don't use the additional functionality it is safe to run a 'WebKit-enabled' PyObjC on systems without Safari 1.0.
a class, this information is automaticly deduced from the list of implemented methods. You'll still a runtime error if you implement some methods of a protocol and one of the unimplemented methods is required.
It is now possible to use instances of Carbon.CF types in places where Objective-C objects are expected. And to explicitly convert between the two.
Note: this requires Python 2.3.
NSMovie.initWithMovie_ and NSMovie.QTMovie now use QT.Movie
objects instead of generic pointer wrappers.NSWindow.initWithWindowRef_ and Window.windowRef now use
Carbon.Window objects instead of generic pointer wrappers.pyobjcPopPool and pyobjcPushPool of NSAutoreleasePool
are deprecated. These were introduced when PyObjC did not yet support the
usual method for creating autorelease pools and are no longer necessary.NOTE: You could create weakrefs in previous versions, but those would expire as soon as the last reference from Python died, not when the Objective-C object died, therefore code that uses weakrefs to Objective-C objects is almost certainly incorrect.
objc.lookup_class -> objc.lookUpClass
objc.selector arguments/attributes:
is_initializer -> isInitializer
is_allocator -> isAlloc
donates_ref -> doesDonateReference
is_required -> isRequired
class_method -> isClassMethod
defining_class -> definingClass
returns_self -> returnsSelf
argument_types -> argumentTypes
return_type -> returnType
objc.get_class_list -> objc.getClassList
o Adjusting Setup, commenting out NeXT definition and enabling GNU ones; o make -f Makefile.pre.in boot o make static
pyobjc.((void *) 1).Class() syntax. You
select the right initializer selector with the init keyword parameter.framep = aView.getFrame__.pack_argument (0) aView.getFrame__ (framep) frame = aView.getFrame__.unpack_argument (0, framep)
-ObjC to the importdl.o
build rule:importdl.o: importdl.c $(CC) -ObjC -c $(CFLAGS) -I$(DLINCLDIR) $(srcdir)/importdl.c
*shared*, and remove -u libNeXT_s -lNeXT_s from it.make: this will update various files, in particular
Modules/Makefile.-u libNeXT_s -lNeXT_s to SYSLIBS:SYSLIBS= $(LIBM) $(LIBC) -u libNeXT_s -lNeXT_s
make again