Commits

Bill Bumgarner  committed 873fb52

Added a bunch of notes and text. Cleaned up the various examples.

  • Participants
  • Parent commits 604313f

Comments (0)

Files changed (12)

File pyobjc/ChangeLog

+2002-10-11  Bill Bumgarner  <bbum@codefab.com>
+
+	* Removed various debugging/development noise from startup.
+
+	* Regenerated various incs in Modules/Cocoa based on new scripts.
+
+	* Updated Examples/WebServicesTool to be compatible with Apple
+	supplied Python.  Created a new main() implementation that
+	transfers control to '/usr/bin/python' via execve().
+
+	* Modules/Cocoa/scripts: Modified all scripts to use 0/1 instead
+	of False/True for compatibility with Python 2.2.  Modified scripts
+	that generate a table of information to emit the 'static' keyword
+	at the head of the declaration.  This fixes a namespace collision
+	with the Apple supplied Python.
+	
+
 2002-10-10 Ronald Oussoren <oussoren@cistron.nl>
 	* Modules/objc/objc-class.m: Implemented a 'class_traverse' function
 	  For some reason Python 2.2.0 crashes when we inherit tp_traverse

File pyobjc/Examples/00ReadMe.txt

 - dictionary.py
   Use a NS*Dictionary object.
 
-And a number of Cocoa applications. These use the 'Cocoa' package.
+And a number of Cocoa applications. These use the 'AppKit' package.
+
 - CurrencyConverter
   A simple NIB based application
 
 - TableModel
   Shows how to use a NSTableView
 
+- TableModel2
+  Same as TableModel but built as a standard Cocoa Project Builder project.
+
+- Web Services Tool
+  Another Project Builder Cocoa project.  Quiries an XML-RPC enabled web
+  server for the methods that it implements.
+
 - Todo
   A more complex NIB based applications. This is a document-based application.
   The code is a translation into pyton of an example project in 

File pyobjc/Examples/TableModel2/README.txt

 
 Of course, if you localize the python scripts, they won't be automatically found.   However, this would be easy to fix by calling NSBundle's -preferredLocalizations method and adding the associated localization directories to sys.path.
 
-To create a new PyCocoa project in Project Builder, do the following.  Of course, this assumes that pyobjc is correctly installed.   This has been tested with python built via Fink -- it should work fine with any build of python.  Unfortunately, it will not work with the Python shipped with OS X as that distribution is incomplete -- it lacks a library to link against (either dynamic or static).
+To create a new PyCocoa project in Project Builder, do the following.  Of course, this assumes that pyobjc is correctly installed.  This has been tested both with the Fink build of Python and with the Apple supplied version of Python.
 
 1. Create a new Cocoa Application or Cocoa Document-based Application
 
-2. Add libpython2.2.a to project (or Python.framework, if using the framework build).  For a standard Fink installation, the library will be in /sw/lib/python2.2/config/.
+2. Replace the main.m in the project with the main.m from this example.
 
-3. If not using the framework build, add the python include path to the project's search path (/sw/include/python2.2/ for Fink).
+3. Add the key 'PrincipalPythonFile' to the Info.plist.  The value is the name of the Python file that you want to be loaded first as the application starts up.  Whatever Python file is chosen, it should take care of loading any other Python files necessary to define the various classes necessary for application startup.   If this key is not defined, the main() function will try to load the file 'Main.py'.   If that file is not found, the application will raise an exception and exit.
 
-4. Replace the main.m in the project with the main.m from this example.
+If you want to create a project that will create a standalone Cocoa application that contains all the resources necessary to run the application, perform the following additional steps:
 
-5. Add the key 'PrincipalPythonFile' to the Info.plist.  The value is the name of the Python file that you want to be loaded first as the application starts up.  Whatever Python file is chosen, it should take care of loading any other Python files necessary to define the various classes necessary for application startup.   If this key is not defined, the main() function will try to load the file 'Main.py'.   If that file is not found, the application will raise an exception and exit.
+4. [optionally] Create a new group called 'pyobjc'.   This is merely cosmetic.
 
-6. Add '-undefined suppress -force_flat_namespace' to the linker flags for the project.  You can also turn off the prebinding feature as it doesn't work anyway.
+5. Add a Copy Files phase to the project.
 
-NOTE:  See the Web Services Tool example as it implements an application that is intended to actually do something useful (beyond the very useful task of testing the PyObjC module).  Also -- step 5 should likely be skipped.  Instead, add a Main.py file to your project that imports all of the python files that define classes necessary for App startup -- see the Web Services Example...
+6. Drag in the AppKit, Foundation, and objc directories from /sw/lib/python2.2/site-packages/ and create absolute path references (you can copy the folders into the project, but it isn't a requirement unless there will be developers contributing to the project that do not have pyobjc installed). 
 
+7. Add the AppKit, Foundation, and objc to the Copy Files phase. 
+
+8. Set Copy Files phase to copy the three directories into the Resources area of the wrapper.
+
+9. Set the Copy Files phase to copy the three files into a subdirectory named 'pyobjc' [optional, but keeps the Resources directory more organized].
+
+If you want to mix in compiled Objective-C classes, add a bundle or framework target to your project.   Then, in the Main.py (or equivalent), load the framework or bundle using the NSBundle API as normal.  Because the main class passes control entirely to the python command-line executable, classes linked into the binary in the traditional fashion (by simply adding the source files to the project) will not be available at runtime.
+

File pyobjc/Examples/TableModel2/TableModel.py

-from Foundation import NSObject
-from Foundation import NSProcessInfo
-from AppKit import NSApplicationMain
-from objc import selector
 import sys
+import os.path
 
-class PyModel (NSObject):
+sys.path.insert(0, os.path.join(sys.path[0], "pyobjc"))
+
+import objc
+import Foundation
+import AppKit
+
+class PyModel (Foundation.NSObject):
 	__slots__  = ('rowcount')
 
-	def awakeFromNib(self):
-		self.rowcount = 10
-		return self
-
 	def init(self):
+		print "init"
 		self.rowcount = 10
 		return self
 
 		print "numerOfRowsInTableView: called"
 		return self.rowcount
 
-	numberOfRowsInTableView_ = selector(numberOfRowsInTableView_, signature="i@:@")
-
-	def tableView_objectValueForTableColumn_row_(self, 
-			aTableView, aTableColumn, rowIndex):
+	def tableView_objectValueForTableColumn_row_(self, aTableView, aTableColumn, rowIndex):
 		print "tableView:objectValueForTableColumn:row: called"
 		return "{%s, %d}"%(aTableColumn.identifier(), rowIndex)
 
-	tableView_objectValueForTableColumn_row_ = selector(tableView_objectValueForTableColumn_row_, signature='@@:@@i')
+	tableView_objectValueForTableColumn_row_ = objc.selector(tableView_objectValueForTableColumn_row_, signature='@@:@@i')
+	numberOfRowsInTableView_ = objc.selector(numberOfRowsInTableView_, signature="i@:@")
+
+sys.exit( AppKit.NSApplicationMain(sys.argv) )

File pyobjc/Examples/TableModel2/TableModel2.pbproj/project.pbxproj

 //102
 //103
 //104
-		1058C7A0FEA54F0111CA2CBB = {
-			children = (
-				F67592030341FC8E01336B42,
-				F67592040341FC8E01336B42,
-				29B97325FDCFA39411CA2CEA,
-				1058C7A1FEA54F0111CA2CBB,
-			);
-			isa = PBXGroup;
-			name = "Linked Frameworks";
-			refType = 4;
-		};
 		1058C7A1FEA54F0111CA2CBB = {
 			isa = PBXFrameworkReference;
 			name = Cocoa.framework;
 			path = /System/Library/Frameworks/Cocoa.framework;
 			refType = 0;
 		};
-		1058C7A2FEA54F0111CA2CBB = {
-			children = (
-				29B97324FDCFA39411CA2CEA,
-			);
-			isa = PBXGroup;
-			name = "Other Frameworks";
-			refType = 4;
-		};
-		1058C7A3FEA54F0111CA2CBB = {
-			fileRef = 1058C7A1FEA54F0111CA2CBB;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 //100
 //101
 //102
 		};
 		29B97317FDCFA39411CA2CEA = {
 			children = (
+				F61BA2AC0357996801C36587,
 				089C165CFE840E0CC02AAC07,
 				F67591E6034123A101336B42,
 			);
 		};
 		29B97323FDCFA39411CA2CEA = {
 			children = (
-				1058C7A0FEA54F0111CA2CBB,
-				1058C7A2FEA54F0111CA2CBB,
-				F67591EB0341244601336B42,
+				29B97325FDCFA39411CA2CEA,
+				1058C7A1FEA54F0111CA2CBB,
+				29B97324FDCFA39411CA2CEA,
 			);
 			isa = PBXGroup;
 			name = Frameworks;
 		};
 		29B97326FDCFA39411CA2CEA = {
 			buildPhases = (
+				F61BA2B4035799BC01C36587,
 				29B97327FDCFA39411CA2CEA,
 				29B97328FDCFA39411CA2CEA,
 				29B9732BFDCFA39411CA2CEA,
 		29B9732DFDCFA39411CA2CEA = {
 			buildActionMask = 2147483647;
 			files = (
-				1058C7A3FEA54F0111CA2CBB,
 				F67591FA0341FC6601336B42,
-				F67595680341FC9001336B42,
-				F67595690341FC9001336B42,
-				F69197E60342BCD401B4D85B,
 			);
 			isa = PBXFrameworksBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
 //F62
 //F63
 //F64
+		F61BA2AC0357996801C36587 = {
+			children = (
+				F61BA2AD035799A001C36587,
+				F61BA2AE035799A001C36587,
+				F61BA2AF035799A001C36587,
+			);
+			isa = PBXGroup;
+			name = pyobjc;
+			path = "";
+			refType = 4;
+		};
+		F61BA2AD035799A001C36587 = {
+			includeInIndex = 1;
+			isa = PBXFolderReference;
+			name = AppKit;
+			path = "/usr/lib/python2.2/site-packages/AppKit";
+			refType = 0;
+		};
+		F61BA2AE035799A001C36587 = {
+			includeInIndex = 1;
+			isa = PBXFolderReference;
+			name = Foundation;
+			path = "/usr/lib/python2.2/site-packages/Foundation";
+			refType = 0;
+		};
+		F61BA2AF035799A001C36587 = {
+			includeInIndex = 1;
+			isa = PBXFolderReference;
+			name = objc;
+			path = "/usr/lib/python2.2/site-packages/objc";
+			refType = 0;
+		};
+		F61BA2B4035799BC01C36587 = {
+			buildActionMask = 8;
+			dstPath = pyobjc;
+			dstSubfolderSpec = 7;
+			files = (
+				F61BA2B7035799D301C36587,
+				F61BA2B9035799DD01C36587,
+				F61BA2BA035799E001C36587,
+			);
+			isa = PBXCopyFilesBuildPhase;
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+		F61BA2B7035799D301C36587 = {
+			fileRef = F61BA2AF035799A001C36587;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F61BA2B9035799DD01C36587 = {
+			fileRef = F61BA2AD035799A001C36587;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F61BA2BA035799E001C36587 = {
+			fileRef = F61BA2AE035799A001C36587;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		F67591E6034123A101336B42 = {
 			children = (
 				F67591E7034123A101336B42,
 			settings = {
 			};
 		};
-		F67591EB0341244601336B42 = {
-			isa = PBXFileReference;
-			name = libpython2.2.a;
-			path = /sw/lib/python2.2/config/libpython2.2.a;
-			refType = 0;
-		};
 		F67591ED0341252E01336B42 = {
 			isa = PBXFileReference;
 			path = README.txt;
 			settings = {
 			};
 		};
-		F67592030341FC8E01336B42 = {
-			isa = PBXFrameworkReference;
-			name = CoreFoundation.framework;
-			path = /System/Library/Frameworks/CoreFoundation.framework;
-			refType = 0;
-		};
-		F67592040341FC8E01336B42 = {
-			isa = PBXFrameworkReference;
-			name = CoreServices.framework;
-			path = /System/Library/Frameworks/CoreServices.framework;
-			refType = 0;
-		};
-		F67595680341FC9001336B42 = {
-			fileRef = F67592030341FC8E01336B42;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F67595690341FC9001336B42 = {
-			fileRef = F67592040341FC8E01336B42;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
-		F69197E60342BCD401B4D85B = {
-			fileRef = F67591EB0341244601336B42;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 	};
 	rootObject = 29B97313FDCFA39411CA2CEA;
 }

File pyobjc/Examples/TableModel2/main.m

-#import <Python.h>
+/*
+ This main file uses execve() to transfer control of execution to the standard command line python interpreter.   As such, compiled classes in the project will not actually be linked into the runtime as execve() effectively overlays the existing process with the process being called -- in this case the python command line tool.
+
+ To use compiled classes with this main, create a separate bundle target and load the bundle in the Main.py file.
+
+ This style of execution works with the Apple provided version of Python.
+ */
+
 #import <Foundation/Foundation.h>
 #import <sys/param.h>
+#import <unistd.h>
 
-int pyobjc_main(int argc, const char *argv[])
+int pyobjc_main(int argc, char * const *argv, char *envp[])
 {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSString *pythonBinPath = [[NSUserDefaults standardUserDefaults] stringForKey: @"PythonBinPath"];
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+  const char **childArgv = alloca(sizeof(char *) * (argc + 3));
+  const char *pythonBinPathPtr;
+  const char *mainPyPathPtr;
+  int i;
 
-    pythonBinPath = pythonBinPath ? pythonBinPath : @"/usr/bin/python";
-    [pythonBinPath retain];
-    Py_SetProgramName((char *)[pythonBinPath cString]); 
-    Py_Initialize();
+  NSString *pythonBinPath = [[NSUserDefaults standardUserDefaults] stringForKey: @"PythonBinPath"];
+  pythonBinPath = pythonBinPath ? pythonBinPath : @"/usr/bin/python";
+  [pythonBinPath retain];
+  pythonBinPathPtr = [pythonBinPath cString];
 
-    NSString *mainPyFile = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"PrincipalPythonFile"];
-    NSString *mainPyPath = nil;
+  NSString *mainPyFile = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"PrincipalPythonFile"];
+  NSString *mainPyPath = nil;
 
-    if (mainPyFile)
-        mainPyPath = [[NSBundle mainBundle] pathForResource: mainPyFile ofType: nil];
+  if (mainPyFile)
+    mainPyPath = [[NSBundle mainBundle] pathForResource: mainPyFile ofType: nil];
 
-    if ( !mainPyPath ) {
-        NSLog(@"*** WARNING *** PrincipalPythonFile key either did not exist in Info.plist or the file it referred to did not exist.  Trying 'Main.py'.");
-        mainPyPath = [[NSBundle mainBundle] pathForResource: @"Main.py" ofType: nil];
-    }
+  if ( !mainPyPath )
+    mainPyPath = [[NSBundle mainBundle] pathForResource: @"Main.py" ofType: nil];
 
-    if ( !mainPyPath )
-        [NSException raise: NSInternalInconsistencyException
-                    format: @"%s:%d pyobjc_main() Failed to find main python entry point for application.  Exiting.", __FILE__, __LINE__];
-    [mainPyPath retain];
+  if ( !mainPyPath )
+    [NSException raise: NSInternalInconsistencyException
+                format: @"%s:%d pyobjc_main() Failed to find main python entry point for application.  Exiting.", __FILE__, __LINE__];
+  [mainPyPath retain];
+  mainPyPathPtr = [mainPyPath cString];
 
-    FILE *mainPy = fopen([mainPyPath cString], "r");
-    int result = PyRun_SimpleFile(mainPy, (char *)[[mainPyPath lastPathComponent] cString]);
+  childArgv[0] = argv[0];
+  childArgv[1] = mainPyPathPtr;
+  for (i = 1; i<argc; i++)
+    childArgv[i+2] = argv[i];
+  childArgv[i+2] = NULL;
 
-    if ( result != 0 )
-        [NSException raise: NSInternalInconsistencyException
-                    format: @"%s:%d pyobjc_main() Failed to run the python file at '%@'.", __FILE__, __LINE__, mainPyPath];
-    
-    [pool release];
+  [pool release];
 
-    return NSApplicationMain(argc, argv);
+  return execve(pythonBinPathPtr, (char **)childArgv, envp);
 }
 
-int main(int argc, const char *argv[])
+int main(int argc, char * const *argv, char *envp[])
 {
-    return pyobjc_main(argc, argv);
+  return pyobjc_main(argc, argv, envp);
 }

File 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.
+
 See:
 	http://pyobjc.sourceforge.net/
 	

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

 //102
 //103
 //104
-		1058C7A0FEA54F0111CA2CBB = {
-			children = (
-				1058C7A1FEA54F0111CA2CBB,
-			);
-			isa = PBXGroup;
-			name = "Linked Frameworks";
-			refType = 4;
-		};
 		1058C7A1FEA54F0111CA2CBB = {
 			isa = PBXFrameworkReference;
 			name = Cocoa.framework;
 			path = /System/Library/Frameworks/Cocoa.framework;
 			refType = 0;
 		};
-		1058C7A2FEA54F0111CA2CBB = {
-			children = (
-				29B97325FDCFA39411CA2CEA,
-				29B97324FDCFA39411CA2CEA,
-			);
-			isa = PBXGroup;
-			name = "Other Frameworks";
-			refType = 4;
-		};
-		1058C7A3FEA54F0111CA2CBB = {
-			fileRef = 1058C7A1FEA54F0111CA2CBB;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 //100
 //101
 //102
 		};
 		29B97323FDCFA39411CA2CEA = {
 			children = (
-				1058C7A0FEA54F0111CA2CBB,
-				1058C7A2FEA54F0111CA2CBB,
-				F6646A57034494A401F2B36F,
+				29B97325FDCFA39411CA2CEA,
+				29B97324FDCFA39411CA2CEA,
+				1058C7A1FEA54F0111CA2CBB,
 			);
 			isa = PBXGroup;
 			name = Frameworks;
 			);
 			buildSettings = {
 				FRAMEWORK_SEARCH_PATHS = "";
-				HEADER_SEARCH_PATHS = /sw/include/python2.2;
+				HEADER_SEARCH_PATHS = "";
 				INSTALL_PATH = "$(HOME)/Applications";
-				LIBRARY_SEARCH_PATHS = /sw/lib/python2.2/config;
+				LIBRARY_SEARCH_PATHS = "";
 				OTHER_CFLAGS = "";
 				OTHER_LDFLAGS = "-undefined suppress -force_flat_namespace";
 				PREBINDING = NO;
 		29B9732DFDCFA39411CA2CEA = {
 			buildActionMask = 2147483647;
 			files = (
-				1058C7A3FEA54F0111CA2CBB,
+				F61BA28D0357963801C36587,
 			);
 			isa = PBXFrameworksBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
 //F62
 //F63
 //F64
+		F61BA28D0357963801C36587 = {
+			fileRef = 29B97325FDCFA39411CA2CEA;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		F62CEFA50357242601718D22 = {
 			buildActionMask = 8;
 			dstPath = pyobjc;
 			dependencies = (
 			);
 			isa = PBXLegacyTarget;
-			name = "Copy Files";
+			name = "Copy Files (Install)";
 			productName = "Copy Files";
 			settingsToExpand = 6;
 			settingsToPassInEnvironment = 287;
 			settings = {
 			};
 		};
-		F6646A57034494A401F2B36F = {
-			isa = PBXFileReference;
-			name = libpython2.2.a;
-			path = /sw/lib/python2.2/config/libpython2.2.a;
-			refType = 0;
-		};
 		F6646A5C0344985501F2B36F = {
 			isa = PBXFileReference;
 			path = WSTConnectionWindowControllerClass.py;

File pyobjc/Examples/WebServicesTool/main-embedded-interpreter.m

+#error The project does not use this file.  It is left here both for reference purposes (if anyone is interested in going the embedded interpreter route) and in case Apple ships the Python library in OS X (the embedded interpreter is actually more efficient). 
+
 /*
  This main file can be used in cases where the developer desires to embed the python interpreter directly into the application.   The pyobjc_main() function initializes the python interpreter in an embedded context.
 

File pyobjc/LICENSE.txt

+(This is the MIT license)
+
+Copyright 2002 - Bill Bumgarner, Ronald Oussoren, Steve Majewski, Lele Gaifax, et.al.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 - Version bumped to A.B.C
 
-- Requires Python 2.3, and on MacOS X a framework install of python
-
 - Support for the GNU runtime is even less functional than before
 
 - Subclassing Objective-C classes from Python, including the addition
 
 - Documentation: See the directory 'docs'
 
+- Can build standalone Cocoa applications based entirely on Python
+without requiring that user installs anything extra.
+
 Version 2002-01-30 (January 30, 2002):
 
 - Version bumped to 0.6.1 ( __version__ is now a PyString )

File pyobjc/README

   GUI applications (see Examples/iClass).
 - Apple's python 2.2 on 10.2
   Same issues as Finks's python 2.2. 
-  This option is hardly tested at all, but seems to work.
 
 ----
 Older README: