Anonymous avatar Anonymous committed aa5cdb0

Many, many changes in preparation for a 0.8 release. ChangeLog should contain a brief description of all of the changes.

Comments (0)

Files changed (18)

 everything necessary to deal with +stringWithFormat: or
 +arrayWithObjects: type API-- two very different beasts [bbum]). 
 
-(-) Does not handle methods returning values of size bigger than
-sizeof (void *).  (This is also hard to fix;  to do so requires either
-creating a bunch of methods with the various possible return types or
-doing some very serious hardcore pointer magic. [bbum])
-  Ronald: Seems to be solved, NSInvocation happily works with large
-  return values.
-
 (-) It's impossible to send messages containing '$' in the name: ObjC
 allows it, Python does not.
 
-(-) Fix issues with API that requires pointers;  NSScanner, for
-example.  See Mssh.
-   Ronald: Infrastructure for this is present, but not optimal.
-
 Known portability problems
 --------------------------
 
-(?) The GNU Runtime is still untested. This is because I wasn't able
-link this module on my NeXT using the latest GNU gcc and runtime:
-multiple defined symbols between libgcc.a and libsys_s.a. Oh, well.
-Once the NeXT support is stable, I will jump on this.
+(?) GNU runtime support is currently non-existant.  We need volunteers
+with GNU runtime expertise to move this forward.  Either that, or a
+recipe for working with the pure-GNU runtime on OS X.
 
-(-) When WITH_FOUNDATION is not defined (it is only when using the GNU
+(?) When WITH_FOUNDATION is not defined (it is only when using the GNU
 Runtime, and will be on OpenStep), Objective-C objects are not
 retained nor released, so the code may access freed objects.
 
-(-) GNUstep Base wants the main function of the application be
+(?) GNUstep Base wants the main function of the application be
 ``gnustep_base_user_main''. NSProcessInfo implements its own ``main''
 function to initialize internal copies of arguments and environ,
 then calls gnustep_base_user_main(). We have to patch pythonrun.c for
 this. 
 
-(-) Does OpenStep behave badly as NeXTSTEP on NSPasteboard's names and
-types?
-
 Others
 ------
 
   Ronald: The ``argument arena'' should be removed completely, we're mostly 
   there.
 
-(-) The ``forward'' mechanism should be revised: the current
-implementation assumes the arguments passed are ALL Objective-C
-objects, since no check is possible...  (Not sure this can be fixed,
-but it should be revisited given that the Mac OS X/XS APIs for
-forwarding are a bit different than the old forward:: APIs. [bbum])
-  Ronald: Fixed. It is now possible to specify the signature of a 
-  python method.
-
-(-) [OC_MemoryStream close] should deallocate the stream's buffer with
-vm_deallocate(). See NXCloseMemory() documentation. (NXStream APIs are
-gone, gone, gone.  But we might want to revit this in light of NSData,
-NSFileHandle, etc... [bbum]?)
-
 (-) Suspicious code is marked with 'XXX'.
 
 Missing
 -------
 
-(*) With Foundation, pythonify_c_value and its counterpart should convert
-to/from NSString and PyStringObject. (What about Unicode???? [bbum])
-  Ronald: Should we? It might be more usefull to provide a function/method
-  to convert NSString values to Python string/unicode objects: NSString
-  seems to have a number of methods without a Python equivalent. I've no
-  problems with automaticly translating Python strings to NSString objects.
+(-) It is impossible to pass a reference to an NSString object into
+    the python runtime such that the fact that it remains an
+    NSString.  As such, it is impossible to invoke NSString specific
+    methods directly.
+2002-12-08  Bill Bumgarner  <bbum@codefab.com>
+    * Examples/WebServicesTool: Added a lot of inline documentation to the
+          python code.
+    * BUGS: Removed some of the already fixed bugs.  Removed legacy
+          information that is no longer relevant.  Added new bugs. Added
+          information to existing bugs.
+	* FIXME: Edited to bring some stuff up to date.
+	* Lib/Foundation/test/test_nsautoreleasepool.py (suite): Added
+	  unittest to test NSAutoreleasePool bug workaround.
+	* Modules/Cocoa/NSAutoreleasePoolSupport.m: Added bogus push/pop
+	  workaround for NSAutoreleasePool bug.
+	* INSTALL: Rewrote a good chunk of the text.  Removed references
+	  to NeXTSTEP.hange
+	* Examples/HelloWorld.py: Reworked example a bit to match modern
+	  usage.
+	  - References classes through AppKit/Foundation, not by looking up
+        	    directly. 
+	  - Added an action method to Hello button so it does something
+	  even when sound is turned off.
+	* Modules/objc/module.m: Fixed import in module.m;  wrong case.
+
 2002-12-01  Bill Bumgarner  <bbum@codefab.com>
 	* cleaned up nsobject unittests slightly [had cruft from nsarray]
 	* added NSAutoreleasePool test
 	  whitespace
 
 2002-11-17  Bill Bumgarner  <bbum@codefab.com>
-
 	* Normalize whitespace
 	* allow extractClasses() to be called multiple times for one nib
 	  (well it was allowed, but now less double work is performed)

pyobjc/Examples/HelloWorld.py

 # HelloWorld.py
 #
-# You have to run this script from the command line with 
-# the full pathname for python:
-#    /usr/local/bin/python HelloWorld.py 
-#
-# or else run from DropShell or gdb. Anything else and you will get a:
-# 	Error 1011 in _sendFinishLaunchingNotification 
-# and it wont work.
-#
-# -- Steve Majewski <sdm7g@Virginia.EDU>
+# The original PyObjC interface example by Steve Majewski.
 #
 
-# You can look up these classes and methods in the Cocoa docs.
 # A quick guide to runtime name mangling:
 #
 #      ObjC 		becomes 	  Python
 #    [ obj method: arg1 withOtherArgs: arg2 ] 
 #				obj.method_withOtherArgs_( arg1, arg2 )
 
+###
+### NOTE:  This is no longer the recommended way to build applications
+### using the pyobjc bridge under with OS X.  In particular, applications
+### work much better if they are constructed in a proper app wrapper.
+###
+### This app does demonstrate that it is possible to build full
+### featured Cocoa apps without InterfaceBuilder.
+###
+
 import objc
-
-# We should import AppKit and Foundation, but don't do that
-# here to show we're using just the basic objective-C bindings.
-NSBundle = objc.lookUpClass('NSBundle')
-NSAutoreleasePool = objc.lookUpClass('NSAutoreleasePool')
-NSApplication = objc.lookUpClass('NSApplication')
-NSWindow = objc.lookUpClass('NSWindow')
-NSButton = objc.lookUpClass('NSButton')
-NSSound = objc.lookUpClass('NSSound')
-NSObject = objc.lookUpClass('NSObject')
+from Foundation import *
+from AppKit import *
 
 class AppDelegate (NSObject):
     def applicationDidFinishLaunching_(self, aNotification):
         print "Hello, World!"
 
+    def sayHello_(self, sender):
+        print "Hello again, World!"
+
 def main():
-
-    # Load Application Framework:
-    NSBundle.bundleWithPath_(
-	'/System/Library/Frameworks/AppKit.framework').load()
-
     NSApp = NSApplication.sharedApplication()
 
     NSApp.setDelegate_( AppDelegate.alloc().init() )
     win.contentView().addSubview_ (hel)
     hel.setBezelStyle_( 4 )
     hel.setTitle_( 'Hello!' )
+    hel.setTarget_( NSApp.delegate() )
+    hel.setAction_( "sayHello:" )
 
     beep = NSSound.alloc()
-    beep.initWithContentsOfFile_byReference_( 
-	'/System/Library/Sounds/tink.aiff', 1 )
+    beep.initWithContentsOfFile_byReference_( '/System/Library/Sounds/Tink.Aiff', 1 )
     hel.setSound_( beep )
 
     bye = NSButton.alloc().initWithFrame_ (((100.0, 10.0), (80.0, 80.0)))
     bye.setTitle_( 'Goodbye!' )
 
     adios = NSSound.alloc()
-    adios.initWithContentsOfFile_byReference_( 
-	'/System/Library/Sounds/Basso.aiff', 1 )
+    adios.initWithContentsOfFile_byReference_(  '/System/Library/Sounds/Basso.aiff', 1 )
     bye.setSound_( adios )
     
     win.display()
-#    win.makeKeyAndOrderFront_ (NSApp)	## This doesn't seem to  work 
     win.orderFrontRegardless()		## but this one does
 
     NSApp.run()    

pyobjc/Examples/WebServicesTool/README.txt

 
 Web Services Tool queries XML-RPC enabled servers via the "standard" introspection methods and displays a summary of the API.   It is implemented in Python using the PyObjC module.
 
-To use the application, simply provide the connection window with an URL to the XML-RPC handler of a web server.  If the server at least implements the listMethods() method, the app will display a list of methods.
+To use the application, simply provide the connection window with an URL to the XML-RPC handler of a web server.  If the server at least implements the listMethods() method, the app will display a list of available methods.
 
 See:
 	http://pyobjc.sourceforge.net/

pyobjc/Examples/WebServicesTool/WSTApplicationDelegateClass.py

-from Foundation import NSObject
-from WSTConnectionWindowControllerClass import WSTConnectionWindowController
+"""
+WSTApplicationDelegateClass
+
+An instance of this class is instantiated in the MainMenu.nib default NIB file.  All outlets and the base class are automatically derived at runtime by the AutoBaseClass mechanism provided by the NibClassBuilder.
+"""
 
 from AppKit import NibClassBuilder
 from AppKit.NibClassBuilder import AutoBaseClass
 
+# Make NibClassBuilder aware of the classes in the main NIB file.
 NibClassBuilder.extractClasses( "MainMenu" )
+
+# WSTApplicationDelegate will automatically inherit from the
+# appropriate ObjC class [NSObject, in this case] and will have the
+# appropriate IBOutlets already defined based on the data found in the
+# NIB file(s) that define the class. 
 class WSTApplicationDelegate(AutoBaseClass):
 
   def newConnectionAction_(self, sender):
+    """Action method fired when the user selects the 'new connection'
+    menu item.  Note that the WSTConnectionWindowControllerClass is
+    defined the first time this method is invoked.
+
+    This kind of lazy evaluation is generally recommended;  it speeds
+    app launch time and it ensures that cycles aren't wasted loading
+    functionality that will never be used.
+
+    (In this case, it is largely moot due to the implementation of
+    applicationDidFinishLaunching_().
+    """
+    from WSTConnectionWindowControllerClass import WSTConnectionWindowController
     WSTConnectionWindowController.connectionWindowController().showWindow_(sender)
 
   def applicationDidFinishLaunching_(self, aNotification):
+    """Create and display a new connection window
+    """
     self.newConnectionAction_(None)

pyobjc/Examples/WebServicesTool/WSTConnectionWindowControllerClass.py

+"""
+Instances of WSTConnectionWindowController are the controlling object
+for the document windows for the Web Services Tool application.
+
+Implements a standard toolbar.
+"""
 from AppKit import *
 from Foundation import *
 
 import string
 import traceback
 
-from AppKit import NibClassBuilder
-from AppKit.NibClassBuilder import AutoBaseClass
+kWSTReloadContentsToolbarItemIdentifier = "WST: Reload Contents Toolbar Identifier"
+"""Identifier for 'reload contents' toolbar item."""
 
-kWSTReloadContentsToolbarItemIdentifier = "WST: Reload Contents Toolbar Identifier"
 kWSTPreferencesToolbarItemIdentifier = "WST: Preferences Toolbar Identifier"
+"""Identifier for 'preferences' toolbar item."""
+
 kWSTUrlTextFieldToolbarItemIdentifier = "WST: URL Textfield Toolbar Identifier"
+"""Idnetifier for URL text field toolbar item."""
 
-def addToolbarItem(self, anIdentifier, aLabel, aPaletteLabel, aToolTip, aTarget, anAction, anItemContent, aMenu):
+def addToolbarItem(aController, anIdentifier, aLabel, aPaletteLabel,
+                   aToolTip, aTarget, anAction, anItemContent, aMenu):
+    """
+    Adds an freshly created item to the toolber defined by
+    aController.  Makes a number of assumptions about the
+    implementation of aController.   It should be refactored into a
+    generically useful toolbar management untility.
+    """
     toolbarItem = NSToolbarItem.alloc().initWithItemIdentifier_(anIdentifier)
     toolbarItem.autorelease()
     
         menuItem.setTitle_( aMenu.title() )
         toolbarItem.setMenuFormRepresentation_(menuItem)
     
-    self._toolbarItems.setObject_forKey_(toolbarItem, anIdentifier)
+    aController._toolbarItems.setObject_forKey_(toolbarItem, anIdentifier)
+
+from AppKit import NibClassBuilder
+from AppKit.NibClassBuilder import AutoBaseClass
 
 NibClassBuilder.extractClasses( "WSTConnection" )
-class WSTConnectionWindowController(AutoBaseClass, NSTableDataSource, NSToolbarDelegate):
+class WSTConnectionWindowController(AutoBaseClass, NSTableDataSource,
+                                    NSToolbarDelegate):
+    """
+    As per the definition in the NIB file,
+    WSTConnectionWindowController is a subclass of
+    NSWindowController.  It acts as a NSTableView data source and
+    implements a standard toolbar.
+    """
     __slots__ = ('_toolbarItems',
         '_toolbarDefaultItemIdentifiers',
         '_toolbarAllowedItemIdentifiers',
         '_methodPrefix' )
     
     def connectionWindowController(self):
-        return WSTConnectionWindowController.alloc().init()
+        """
+        Create and return a default connection window instance.
+        """
+        return WSTConnectionWindowController.alloc().init().autorelease()
            
     def init(self):
+        """
+        Designated initializer.
+
+        Returns self (as per ObjC designated initializer definition,
+        unlike Python's __init__() method).
+        """
         self = self.initWithWindowNibName_("WSTConnection")
 
+        # assignments imply a -retain!
         self._toolbarItems = NSMutableDictionary.dictionary()
         self._toolbarDefaultItemIdentifiers = NSMutableArray.array()
         self._toolbarAllowedItemIdentifiers = NSMutableArray.array()
         return self
     
     def awakeFromNib(self):
+        """
+        Invoked when the NIB file is loaded.  Initializes the various
+        UI widgets.
+        """
         self.retain() # balanced by autorelease() in windowWillClose_
         
         self.statusTextField.setStringValue_("No host specified.")
         self.createToolbar()
         
     def windowWillClose_(self, aNotification):
+        """
+        Clean up when the document window is closed.
+        """
         self.autorelease()
 
     def createToolbar(self):
+        """
+        Creates and configures the toolbar to be used by the window.
+        """
         toolbar = NSToolbar.alloc().initWithIdentifier_("WST Connection Window").autorelease()
         toolbar.setDelegate_(self)
         toolbar.setAllowsUserCustomization_(YES)
             self.urlTextField.setStringValue_(lastURL)
         
     def createToolbarItems(self):
+        """
+        Creates all of the toolbar items that can be made available in
+        the toolbar.  The actual set of available toolbar items is
+        determined by other mechanisms (user defaults, for example).
+        """
         addToolbarItem(self, kWSTReloadContentsToolbarItemIdentifier, "Reload", "Reload", "Reload Contents", None, "reloadVisibleData:", NSImage.imageNamed_("Reload"), None)
         addToolbarItem(self, kWSTPreferencesToolbarItemIdentifier, "Preferences", "Preferences", "Show Preferences", None, "orderFrontPreferences:", NSImage.imageNamed_("Preferences"), None)
         addToolbarItem(self, kWSTUrlTextFieldToolbarItemIdentifier, "URL", "URL", "Server URL", None, None, self.urlTextField, None)
         self._toolbarAllowedItemIdentifiers.addObject_(NSToolbarCustomizeToolbarItemIdentifier)
         
     def toolbarDefaultItemIdentifiers_(self, anIdentifier):
+        """
+        Return an array of toolbar item identifiers that identify the
+        set, in order, of items that should be displayed on the
+        default toolbar.
+        """
         return self._toolbarDefaultItemIdentifiers
 
     def toolbarAllowedItemIdentifiers_(self, anIdentifier):
+        """
+        Return an array of toolbar items that may be used in the toolbar.
+        """
         return self._toolbarAllowedItemIdentifiers
         
-    def toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_(self, toolbar, itemIdentifier, flag):
-        newItem = NSToolbarItem.alloc().initWithItemIdentifier_( itemIdentifier )
+    def toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_(self,
+                                                                 toolbar,
+                                                                 itemIdentifier, flag):
+        """
+        Delegate method fired when the toolbar is about to insert an
+        item into the toolbar.  Item is identified by itemIdentifier.
+
+        Effectively makes a copy of the cached reference instance of
+        the toolbar item identified by itemIdentifier.
+        """
+        newItem = NSToolbarItem.alloc().initWithItemIdentifier_(itemIdentifier)
         item = self._toolbarItems.objectForKey_(itemIdentifier)
         
         newItem.autorelease()
         return newItem  
         
     def setStatusTextFieldMessage_(self, aMessage):
+        """
+        Sets the contents of the statusTextField to aMessage and
+        forces the fileld's contents to be redisplayed.
+        """
         if not aMessage:
             aMessage = "Displaying information about %d methods." % len(self._methods)
         self.statusTextField.setStringValue_(aMessage)
         self.statusTextField.display()
 
     def reloadVisibleData_(self, sender):
+        """
+        Reloads the list of methods and their signatures from the
+        XML-RPC server specified in the urlTextField.  Displays
+        appropriate error messages, if necessary.
+        """
         url = self.urlTextField.stringValue()
         self._methods = []
         self._methodSignatures = {}
             self.setStatusTextFieldMessage_("No URL specified.")
     
     def selectMethodAction_(self, sender):
+        """
+        When the user selects a remote method, this method displays
+        the documentation for that method as returned by the XML-RPC
+        server.  If the method's documentation has been previously
+        queried, the documentation will be retrieved from a cache.
+        """
         selectedRow = self.methodsTable.selectedRow()
         selectedMethod = self._methods[selectedRow]
         
         self.methodDescriptionTextView.setString_(methodDescription)
 
     def numberOfRowsInTableView_(self, aTableView):
+        """
+        Returns the number of methods found on the server.
+        """
         return len(self._methods)
 
     def tableView_objectValueForTableColumn_row_(self, aTableView, aTableColumn, rowIndex):
+        """
+        Returns either the raw method name or the method signature,
+        depending on if a signature had been found on the server.
+        """
         aMethod = self._methods[rowIndex]
         if self._methodSignatures.has_key(aMethod):
             return self._methodSignatures[aMethod]
 
     ### adjust method decls to be in line with ObjC requirements
     connectionWindowController = selector(connectionWindowController, class_method=1)
+    """
+    Declares that the method connectionWindowController is actually a
+    class method.  This is the one piece of non-automatic glue
+    required to make this class work.   If we used a more pythonic
+    module level function to create instances of this class, this
+    could easily be eliminated.
+    """

pyobjc/Examples/WebServicesTool/Web Services Tool.pbproj/project.pbxproj

 				4A9504CDFFE6A4B311CA0CBA,
 				F62CEFCE0357591F01718D22,
 			);
+			hasScannedForEncodings = 1;
 			isa = PBXProject;
 			mainGroup = 29B97314FDCFA39411CA2CEA;
 			projectDirPath = "";
 </dict>
 </plist>
 ";
-			shouldUseHeadermap = 1;
 		};
 		29B97327FDCFA39411CA2CEA = {
 			buildActionMask = 2147483647;
 //4A2
 //4A3
 //4A4
+//770
+//771
+//772
+//773
+//774
+		77E90B1C03A29B42002FB0D7 = {
+			isa = PBXFileReference;
+			name = _socket.so;
+			path = "/usr/lib/python2.2/site-packages/_socket.so";
+			refType = 0;
+		};
+		77E90B1D03A29B42002FB0D7 = {
+			fileRef = 77E90B1C03A29B42002FB0D7;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//770
+//771
+//772
+//773
+//774
 //F60
 //F61
 //F62
 				F62CEFC0035724EB01718D22,
 				F62CEFC40357585C01718D22,
 				F62CEFC50357585C01718D22,
+				77E90B1D03A29B42002FB0D7,
 			);
 			isa = PBXCopyFilesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 1;
 				F62CEFA6035724EB01718D22,
 				F62CEFAD035724EB01718D22,
 				F62CEFB2035724EB01718D22,
+				77E90B1C03A29B42002FB0D7,
 			);
 			isa = PBXGroup;
 			name = pyobjc;
 			refType = 4;
 		};
 		F62CEFC20357585C01718D22 = {
+			fileEncoding = 30;
 			isa = PBXFileReference;
 			path = LICENSE.txt;
 			refType = 2;
 		};
 		F62CEFC30357585C01718D22 = {
+			fileEncoding = 30;
 			isa = PBXFileReference;
 			path = README.txt;
 			refType = 2;
 			isa = PBXAggregateTarget;
 			name = Packaging;
 			productName = Packaging;
-			shouldUseHeadermap = 0;
 		};
 		F62CEFC70357587501718D22 = {
 			isa = PBXTargetDependency;
 			);
 			isa = PBXLegacyTarget;
 			name = "Copy Files (Install)";
+			passBuildSettingsInEnvironment = 1;
 			productName = "Copy Files";
 			settingsToExpand = 6;
 			settingsToPassInEnvironment = 287;
 			settingsToPassOnCommandLine = 280;
-			shouldUseHeadermap = 0;
 		};
 		F62CEFCB035758DE01718D22 = {
 			isa = PBXTargetDependency;
 			};
 		};
 		F6AAC478035708BD01B76035 = {
+			fileEncoding = 30;
 			indentWidth = 4;
 			isa = PBXFileReference;
 			path = "bin-python-main.m";

pyobjc/Examples/WebServicesTool/__main__.py

 import sys
 
+# import pyobjc
 import objc
 import Foundation
 import AppKit
 import WSTApplicationDelegateClass
 import WSTConnectionWindowControllerClass
 
+# pass control to the AppKit
 sys.exit( AppKit.NSApplicationMain(sys.argv) )
-[bbum] This needs to be automated.  How to build a package:
-	- install module into /tmp/pyobjc/
-	- cd into Project Templates
-	- ./install.sh /tmp/pyobjc/
-	- open the package template
-	- cmd-k to make the package
-
 * [ronald] OC_PythonObject.m contains cruft from the initial experimentations.
 
 * [ronald] MallocDebug.app causes a crash in pyobjc (Try running TableModel in
 * [ronald] Restructure header files in Modules/objc
 
 * [ronald] Contents MANIFEST is no longer valid
+  [bbum] Anyway to move to a MANIFEST.in and have most of MANIFEST be
+  autogenerated?  It is a nightmare to maintain, as is.
 
-* [ronald] NSAutoreleasePool raises an exception when you use 'retain'. NSInvocation 
-  calls 'retain' on the receiver (at least in the way we use it...)
+* [ronald] NSAutoreleasePool raises an exception when you use
+  'retain'. NSInvocation    calls 'retain' on the receiver (at least in
+  the way we use it...)
 
   Luckily users normally don't have to create an autorelease pool.
 
+  [bbum] Not true.  Anyone using PyObjC to build shell script like
+  functionality will need to   create an autorelease pool at the
+  beginning of the script to avoid lots of warnings about leaking
+  objects.
+
 * [ronald] pyobjc-0.6.1 and earlier contain some code that is questionable in
   newer releases of Python. Need to check if all code, and repair where 
   necessary.
    objective-C code. It might be usefull to bug-out when the retainCount falls
    to 0, which would be a bug]
 
-* add detection of Mac OS X vs. Mac OS X Server so that references to obsoleted APIs can be removed from the OSX build.
-  [Ronald: Is this relevant? Current version of Mac OS X and Mac OS X Server
-   seem to be fully compatibel]
-
 * fix multithreading support in the method dispatch mechanisms.  In particular, I believe [but didn't dig] that the argument decoding/encoding stuff is not thread safe in that it uses static variables?
   [Ronald: the argument_arena code is not thread-safe, and there are some
    static buffers lurking in other parts of the code. The arguments_arena
 Building the Module
 ===================
 
-*** 
-*** NOTE1: On MacOS X you must build and install Python as a framework
-***	  (check Mac/OSX/README in the Python tree on how to do this).
-***
-*** NOTE2: You'll need Python 2.3 or later, Python 2.2 is NOT good enough!
-***
-
 The module uses the distutils package included with Python 2.0 and
 beyond.   This package provides a single interface for building and
 packaging the module.   To see usage documentation for the module,
 The setup.py system can also be used to create source and binary
 distribution archives automatically.
 
+Use 'sudo' to install the pyobjc module into a the Apple supplied
+python's site-packages directory on OS X 10.2 and greater:
 
-XXX Ronald: Everything below this should be updated.
+% sudo python setup.py install
 
-Demos
-=====
+If you have multiple versions of python installed on your system, the
+above will only install pyobjc for whatever version of python is the
+default on the command line.   Make sure you are installing python
+against the correct version of python.
 
-If it works and you are on NeXTSTEP (or just curious ;-) go in
-Demo/ObjC and try the examples: though very simple, they give the
-idea; both are based on NeXTSTEP' bundles, so you need that OS to
-enjoy them.
+Examples
+========
 
-The LittleButtonedWindow demo puts a window on the screen, with a
-button in it.
+The examples directory contains a number of projects that demonstrate
+various features of the PyObjC bridge. The scripts at the top level of
+the examples directory were mostly written to test a particular
+feature of the bridge (or document a bug until a fix could be found).
 
-XXX NOT UPDATED YET XXX
+CurrencyConverter and TableModel are both examples of standalone
+Cocoa-Python applications.  To build and execute 
 
-AlertPanel will put an NXAlertPanel on the screen, completely piloted
-by the Python script;
+% cd TableModel
+% python buildapp.py build
 
-Forward will attach a Python instance method as the `action' of an
-ObjC object and then that object will be asked to perform an unknown
-method on the Python object... intricated to explain, easier to see ;-)
+The WebServicesTool and TableModel2 are both examples of Cocoa-Python
+applications created via the Cocoa-Python project template found in
+the "Project Templattes" directory.  Use Project Builder to build the
+applications.
 
-ShellText is actually one of the shorter ways to build a NeXTSTEP
-application able to show in its own window its *entire* source code ;-)
+Project Templates
+=================
 
+The "Project Templates" directory contains project templates for
+project builder.  Currently, there is one project builder template;  a
+Cocoa-Python Application project template.   When installed, this adds
+a project to Project Builder's project menu that allows new Cocoa
+applications implemented entirely in Python to be created from within
+Project Builder (in the same fashion as any other project).
 
-Documentation
-=============
+To install, simply copy the project template into the Project Builder
+project templates directory (or create a symlink).
 
-The documentation of the module is contained in three LaTeX sources in
-the `Doc/' directory: if you want include them in the Library manual,
-simply add the following lines
-
-        \input{libPyObjC}
-
-near the end of the file `Doc/lib.tex', just before the inclusion of the
-index (\input{lib.ind}).
+More information on project templates can be found in the Project
+Builder documentation and/or release notes.

pyobjc/Lib/Foundation/test/test_nsautoreleasepool.py

 from Foundation import *
 
 class TestNSAutoreleasePoolInteraction( unittest.TestCase ):
+#    def testNSAutoreleasePool( self ):
+#        pool = NSAutoreleasePool.alloc().init()
+#        bar = NSMutableArray.array()
+#        pool.release()
+#        bar.addObject_( "a" ) # should still exist because of python GC
+
     def testNSAutoreleasePool( self ):
-        pool = NSAutoreleasePool.alloc().init()
+        NSAutoreleasePool.pyobjcPushPool()
         bar = NSMutableArray.array()
-        pool.release()
-        bar.addObject( "a", "b", "c" )
+        NSAutoreleasePool.pyobjcPopPool()
+        bar.addObject_( "a" ) # should still exist because of python GC
 
 def suite():
     suite = unittest.TestSuite()
 
 if __name__ == '__main__':
     unittest.main( )
-

pyobjc/Lib/objc/test/test_objc.py

 
     def testVarargsInvocation(self):
         objc.runtime.NSArray.arrayWithObjects_("foo", "bar", None)
-        
 
 def suite():
     suite = unittest.TestSuite()

pyobjc/Modules/Cocoa/NSAutoreleasePoolSupport.m

+#import <Foundation/Foundation.h>
+
+static NSMutableArray *_poolStack;
+
+@interface NSAutoreleasePool(PyObjCPushPopSupport)
+@end
+@implementation NSAutoreleasePool (PyObjCPushPopSupport)
++ (void) load
+{
+  _poolStack = [[NSMutableArray alloc] init];
+}
+
++ (void) pyobjcPushPool
+{
+  NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
+  [_poolStack addObject: [NSValue valueWithNonretainedObject: p]];
+}
+
++ (void) pyobjcPopPool
+{
+  NSAutoreleasePool *p = [_poolStack lastObject];
+  [p release];
+  [_poolStack removeLastObject];
+}
+@end

pyobjc/Modules/objc/module.m

 #include <Python.h>
 #include "pyobjc.h"
 #include <stddef.h>
-#include <Foundation/NSAutoReleasePool.h>
+#include <Foundation/NSAutoreleasePool.h>
 #include "objc_support.h"
 
 NSAutoreleasePool* ObjC_global_release_pool = nil;

pyobjc/Modules/objc/pyobjc.h

 #include "OC_PythonDictionary.h"
 #include "super-call.h"
 
-#define OBJC_VERSION "0.7.1"
+#define OBJC_VERSION "0.8"
 
 #ifdef MACOSX
 
 
 WHAT'S NEW:
 
-Version 2002-XX-XX (Someday):
+Version 0.8 (Dec-10-2002):
 
-- Version bumped to A.B.C
-
-- Support for the GNU runtime is even less functional than before
+- GNUStep support has been removed for lack of support.  Volunteers
+  needed.
 
 - Subclassing Objective-C classes from Python, including the addition
   of instance variables (like 'IBOutlet's)
 - Generic support for pass-by-reference arguments
 
 - More complete Cocoa package, including wrappers for a number of 
-  C functions.
+  C functions, enumerated types, and globals.
 
 - More example code
 
 - Documentation: See the directory 'docs'
 
 - Can build standalone Cocoa applications based entirely on Python
-without requiring that user installs anything extra.
+  without requiring that user installs anything extra (requires 10.2).
+
+- Better packaging and wrapper construction tools (borrowed from
+  MacPython).
+
+- An installer package.
+
+- Support for Project Builder based Cocoa-Python projects.
+
+- Unit tests.
 
 Version 2002-01-30 (January 30, 2002):
 

pyobjc/Project Templates/Cocoa-Python Application/bin-python-main.m

   [[NSAutoreleasePool alloc] init];
 
   const char **childArgv = alloca(sizeof(char *) * (argc + 5));
-  char **childEnvp = (char **)envp;
   NSEnumerator *bundleEnumerator = [[NSBundle allFrameworks] reverseObjectEnumerator];
   NSBundle *aBundle;
   NSBundle *mainBundle = [NSBundle mainBundle];
   NSMutableArray *bundlePaths = [NSMutableArray array];
   int i;
+  char** childEnvp;
+  char*  PYTHONPATH = NULL;
+
+  // count entries in environment and find the PYTHONPATH setting, if present
+  for (envc = 0; envp[envc] != NULL; envc++) {
+    if (strncmp(envp[envc], "PYTHONPATH=", sizeof("PYTHONPATH=")-1) == 0) {
+      PYTHONPATH=envp[envc] + sizeof("PYTHONPATH=") - 1;
+      /* No break, we also want to know how large envp is */
+    }
+  }
+
+  childEnvp = alloca(sizeof(char*) * (envc + 10)); // enough for both PYTHONPATH and the DYLD stuff
+  for (envc = 0; envp[envc] != NULL; envc ++) {
+    if (strncmp(envp[envc], "PYTHONPATH=", sizeof("PYTHONPATH=")-1) == 0) {
+      const char* s = [[[NSBundle mainBundle] resourcePath] UTF8String];
+      childEnvp[envc] = alloca(strlen(envp[envc]) + strlen(s) + 2);
+      sprintf(childEnvp[envc], "%s:%s", s, envp[envc]);
+    } else {
+      childEnvp[envc] = envp[i];
+    }
+  }
+  if (PYTHONPATH) {
+    envp[envc] = NULL;
+  } else {
+    const char* s = [[[NSBundle mainBundle] resourcePath] UTF8String];
+    childEnvp[envc] = alloca(sizeof("PYTHONPATH=") + strlen(s));
+    sprintf(childEnvp[envc], "PYTHONPATH=%s", s);
+    childEnvp[envc+1] = NULL;
+  }
 
   // if this is set, it is most likely because of PBX or because the developer is doing something....
   if ( !getenv("DYLD_FRAMEWORK_PATH") ) {
     const char *dyldFrameworkPath = [[NSString stringWithFormat: @"DYLD_FRAMEWORK_PATH=%@", joinedPaths] UTF8String];
     const char *dyldLibraryPath = [[NSString stringWithFormat: @"DYLD_LIBRARY_PATH=%@", joinedPaths] UTF8String];
 
-    for(i=0; envp[i]; i++);
-    childEnvp = malloc( sizeof(char *) * (i+4) );
-
-    bcopy( envp, childEnvp, ( i * sizeof(char *) ) );
-
     childEnvp[i++] = (char *)dyldFrameworkPath;
     childEnvp[i++] = (char *)dyldLibraryPath;
 
 CocoaPackages = [ 'Foundation', 'AppKit' ]
 CocoaExtensions = [
 	  Extension("Foundation._Foundation", 
-		   ["Modules/Cocoa/_Foundation.m"],
+		   ["Modules/Cocoa/_Foundation.m",
+            "Modules/Cocoa/NSAutoreleasePoolSupport.m"],
 		   extra_compile_args=[
 			"-g", "-IModules/objc",  
 		   ],
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.