Skip to content

Commit 3e942e2

Browse files
author
ronald.oussoren
committed
* If BuildApplet.py is used as an applet it starts with a version of
sys.exutable that isn't usuable on an #!-line. That results in generated applets that don't actually work. Work around this problem by resetting sys.executable. * argvemulator.py didn't work on intel macs. This patch fixes this (bug #1491468) git-svn-id: http://svn.python.org/projects/python/trunk@46727 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 26f83a3 commit 3e942e2

2 files changed

Lines changed: 45 additions & 57 deletions

File tree

Lib/plat-mac/argvemulator.py

Lines changed: 33 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from Carbon import AE
88
from Carbon.AppleEvents import *
99
from Carbon import Evt
10+
from Carbon import File
1011
from Carbon.Events import *
1112
import aetools
1213

@@ -16,36 +17,36 @@ class ArgvCollector:
1617

1718
def __init__(self):
1819
self.quitting = 0
19-
self.ae_handlers = {}
2020
# Remove the funny -psn_xxx_xxx argument
2121
if len(sys.argv) > 1 and sys.argv[1][:4] == '-psn':
2222
del sys.argv[1]
23-
self.installaehandler('aevt', 'oapp', self.open_app)
24-
self.installaehandler('aevt', 'odoc', self.open_file)
2523

26-
def installaehandler(self, classe, type, callback):
27-
AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
28-
self.ae_handlers[(classe, type)] = callback
24+
AE.AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, self.__runapp)
25+
AE.AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, self.__openfiles)
2926

3027
def close(self):
31-
for classe, type in self.ae_handlers.keys():
32-
AE.AERemoveEventHandler(classe, type)
28+
AE.AERemoveEventHandler(kCoreEventClass, kAEOpenApplication)
29+
AE.AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments)
3330

3431
def mainloop(self, mask = highLevelEventMask, timeout = 1*60):
32+
# Note: this is not the right way to run an event loop in OSX or even
33+
# "recent" versions of MacOS9. This is however code that has proven
34+
# itself.
3535
stoptime = Evt.TickCount() + timeout
3636
while not self.quitting and Evt.TickCount() < stoptime:
37-
self.dooneevent(mask, timeout)
38-
self.close()
37+
self._dooneevent(mask, timeout)
3938

40-
def _quit(self):
41-
self.quitting = 1
39+
if not self.quitting:
40+
print "argvemulator: timeout waiting for arguments"
4241

43-
def dooneevent(self, mask = highLevelEventMask, timeout = 1*60):
42+
self.close()
43+
44+
def _dooneevent(self, mask = highLevelEventMask, timeout = 1*60):
4445
got, event = Evt.WaitNextEvent(mask, timeout)
4546
if got:
46-
self.lowlevelhandler(event)
47+
self._lowlevelhandler(event)
4748

48-
def lowlevelhandler(self, event):
49+
def _lowlevelhandler(self, event):
4950
what, message, when, where, modifiers = event
5051
h, v = where
5152
if what == kHighLevelEvent:
@@ -60,53 +61,28 @@ def lowlevelhandler(self, event):
6061
else:
6162
print "Unhandled event:", event
6263

63-
def callback_wrapper(self, _request, _reply):
64-
_parameters, _attributes = aetools.unpackevent(_request)
65-
_class = _attributes['evcl'].type
66-
_type = _attributes['evid'].type
67-
68-
if self.ae_handlers.has_key((_class, _type)):
69-
_function = self.ae_handlers[(_class, _type)]
70-
elif self.ae_handlers.has_key((_class, '****')):
71-
_function = self.ae_handlers[(_class, '****')]
72-
elif self.ae_handlers.has_key(('****', '****')):
73-
_function = self.ae_handlers[('****', '****')]
74-
else:
75-
raise 'Cannot happen: AE callback without handler', (_class, _type)
76-
77-
# XXXX Do key-to-name mapping here
78-
79-
_parameters['_attributes'] = _attributes
80-
_parameters['_class'] = _class
81-
_parameters['_type'] = _type
82-
if _parameters.has_key('----'):
83-
_object = _parameters['----']
84-
del _parameters['----']
85-
# The try/except that used to be here can mask programmer errors.
86-
# Let the program crash, the programmer can always add a **args
87-
# to the formal parameter list.
88-
rv = _function(_object, **_parameters)
89-
else:
90-
#Same try/except comment as above
91-
rv = _function(**_parameters)
9264

93-
if rv == None:
94-
aetools.packevent(_reply, {})
95-
else:
96-
aetools.packevent(_reply, {'----':rv})
65+
def _quit(self):
66+
self.quitting = 1
9767

98-
def open_app(self, **args):
68+
def __runapp(self, requestevent, replyevent):
9969
self._quit()
10070

101-
def open_file(self, _object=None, **args):
102-
for alias in _object:
103-
fsr = alias.FSResolveAlias(None)[0]
104-
pathname = fsr.as_pathname()
105-
sys.argv.append(pathname)
106-
self._quit()
71+
def __openfiles(self, requestevent, replyevent):
72+
try:
73+
listdesc = requestevent.AEGetParamDesc(keyDirectObject, typeAEList)
74+
for i in range(listdesc.AECountItems()):
75+
aliasdesc = listdesc.AEGetNthDesc(i+1, typeAlias)[1]
76+
alias = File.Alias(rawdata=aliasdesc.data)
77+
fsref = alias.FSResolveAlias(None)[0]
78+
pathname = fsref.as_pathname()
79+
sys.argv.append(pathname)
80+
except Exception, e:
81+
print "argvemulator.py warning: can't unpack an open document event"
82+
import traceback
83+
traceback.print_exc()
10784

108-
def other(self, _object=None, _class=None, _type=None, **args):
109-
print 'Ignore AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
85+
self._quit()
11086

11187
if __name__ == '__main__':
11288
ArgvCollector().mainloop()

Mac/scripts/BuildApplet.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
import buildtools
1717
import getopt
1818

19+
if not sys.executable.startswith(sys.exec_prefix):
20+
# Oh, the joys of using a python script to bootstrap applicatin bundles
21+
# sys.executable points inside the current application bundle. Because this
22+
# path contains blanks (two of them actually) this path isn't usable on
23+
# #! lines. Reset sys.executable to point to the embedded python interpreter
24+
sys.executable = os.path.join(sys.prefix,
25+
'Resources/Python.app/Contents/MacOS/Python')
26+
27+
# Just in case we're not in a framework:
28+
if not os.path.exists(sys.executable):
29+
sys.executable = os.path.join(sys.exec_prefix, 'bin/python')
30+
1931
def main():
2032
try:
2133
buildapplet()

0 commit comments

Comments
 (0)