An overview of the relevant changes in new, and older, releases.
setValue:forKey:
and
valueForKey:
in Python for all levels in the inheritance hierarchie.__slots__
.-autorelease
instead of -release
to release
values in destructors. This seems to solve at least one memory managment
issue._doFoo_andBar_
in Python will be _doFoo:andBar:
in Objective-C.__foobar__
in Python will stay that way in Objective-C.These changes fix some minor annoyances with the older scheme. Note that the translation from Objective-C to Python is unmodified and is entirely consistent with the modified rules for translating from Python to Objective-C.
__pyobjc_object__
handling.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.AppleScriptKit
Automator
CoreData
DiscRecording
DiscRecordingUI
OSAKit
Quartz
QTKit
SyncServices
XgridFoundation
Documentation 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