[Pythonmac-SIG] Python & MPW ToolServer

Daniel Brotsky dev@brotsky.com
Fri, 9 Nov 2001 13:17:31 -0800


At 10:42 AM -0800 11/8/01, Alan Lillich wrote:
>I need to port a simple testing framework and am looking at both Perl and
>Python.  One of the things I need to do is run simple C stdio programs,
>passing in command line arguments and getting a numeric status back.  This
>is obvious for UNIX (including Mac OS X) and Windows in either language.
>For Mac OS 9 the Perl system function lets you invoke an MPW tool or script
>via ToolServer, exactly what I want.  Looking through the Python
>documentation and SIG archive, it looks like the Python fork and exec
>functions aren't implemented on Mac OS 9, at all let alone using ToolServer.

Alan,

Since the macos module doesn't define system(), I'm guessing that 
Jack didn't feel there was any "obviously right" way in the Mac world 
to simulate the "unix standard C" approach to how apps work.  I'd 
have to say I agree with this, but also that Perl's approach (to use 
MPW/ToolServer) seems as good as any.

The easiest way in MacPython to use ToolServer like this is to use 
the (quite well-developed) AppleEvent infrastructure.  Below I've 
attached source for a simple "aesystem" module I use frequently for 
what you describe needing to do.  Once you've imported aesystem, you 
can do things like:

>>>  aesystem.system('echo "This is a test."')
0
>>>  aesystem.lastOutput
'This is a test.\r'
>>>  aesystem.system('Search -nf -e "nowayjack"', infile=":QuitTS", 
>>>outfile="Dev:Null")
2
>>>  aesystem.lastErrorOutput
'### Search - Pattern not found.\r'

(Notice that the scripts/tools run in ToolServer's curdir, not in Python's.)

Hope this helps.  Contact me off-list if you want something more sophisticated.

     dan

------------
"""aesystem -
A simple example of how to use Apple Events to implement a "system()"
call that invokes ToolServer on the command.

system(cmd, infile = None, outfile = None, errfile = None)

1. Every call to system sets "lastStatus" and "lastOutput" to the 
status and output
produced by the command when executed in ToolServer.  (lastParameters 
and lastAttributes
are set to the values of the AppleEvent result.)

2. system returns lastStatus unless the command result indicates a MacOS error,
in which case os.Error is raised with the errnum as associated value.

3. You can specify ToolServer-understandable pathnames for 
redirection of input,
output, and error streams.  By default, input is Dev:Null, output is captured
and returned to the caller, diagnostics are captured and returned to 
the caller.
(There's a 64K limit to how much can be captured and returned this way.)"""

import os
import aetools

try: server
except NameError: server = aetools.TalkTo("MPSX", 1)

lastStatus = None
lastOutput = None
lastErrorOutput = None
lastScript = None
lastEvent = None
lastReply = None
lastParameters = None
lastAttributes = None

def system(cmd, infile = None, outfile = None, errfile = None):
	global lastStatus, lastOutput, lastErrorOutput
	global lastScript, lastEvent, lastReply, lastParameters, lastAttributes
	cmdline = cmd
	if infile: cmdline += " <" + infile
	if outfile: cmdline += " >" + outfile
	if errfile: cmdline += " " + str(chr(179)) + errfile
	lastScript = "set Exit 0\r" + cmdline + "\rexit {Status}"
	lastEvent = server.newevent("misc", "dosc", {"----" : lastScript})
	(lastReply, lastParameters, lastAttributes) = 
server.sendevent(lastEvent)
	if lastParameters.has_key('stat'): lastStatus = lastParameters['stat']
	else: lastStatus = None
	if lastParameters.has_key('----'): lastOutput = lastParameters['----']
	else: lastOutput = None
	if lastParameters.has_key('diag'): lastErrorOutput = 
lastParameters['diag']
	else: lastErrorOutput = None
	if lastParameters['errn'] != 0:
		raise os.Error, lastParameters['errn']
	return lastStatus