Re: [Pyobjc-dev] execing /usr/bin/python
Brought to you by:
ronaldoussoren
From: Ronald O. <ous...@ci...> - 2002-11-01 20:06:12
|
On Friday, Nov 1, 2002, at 15:55 Europe/Amsterdam, bb...@ma... wrote: > On Friday, November 1, 2002, at 07:05 AM, Jack Jansen wrote: >>> - The python sources are copied to the Resources directory of >>> the application >>> >>> Do we have any control over this? I'd like to be able to convert the >>> sources to bytecode (slightly faster startup, and this makes it >>> harder to change the code). >> Please have a look at BuildApplication (and the underlying freeze >> modules), so you don't go reinventing the wheel. BuildApplication >> first recursively collects all modules used by a script, then >> byte-compiles these and then stuffs them into OS9 resources. The last >> step needs to be modified for OSX, but the first step (which is >> basically shared with freeze) can definitely be used. > > I think we are talking about two different ways of building > applications. ... and I'd like to suppport either way of building applications, if only because I've vi keyboard commands hardwired into my hands (I tend to insert sequences of j/k/l/h into when I'm really concentrated while typing in a GUI editor :-) > >> On vrijdag, nov 1, 2002, at 03:53 Europe/Amsterdam, bb...@ma... >> wrote: >>> On Thursday, October 31, 2002, at 04:42 PM, Ronald Oussoren wrote: >>>> On Thursday, Oct 31, 2002, at 14:20 Europe/Amsterdam, bb...@ma... >>>> wrote: >>>>> ..... >> I think there's a misunderstanding somewhere in the me->ronald->bill >> conversation, as I don't see why Bill's method would be different >> from mine. In other words, please explain if there is... >> >> Here's my scheme, with an example: >> /Applications/foo.app/Contents/MacOS/foo looks for __main__.py in >> Resources, and does >> execve("/Applications/foo.app/Contents/MacOS/python", >> ["/Applications/foo.app/Contents/MacOS/python", >> "/Applications/foo.app/Contents/Resources/__main__.py", >> rest of original argv]) >> and Contents/MacOS/python is a symlink to /usr/bin/python. > > In terms of passing control to the python interpreter, the two > solutions are doing same thing excepting for the symlink and the > direct insertion of the python binary into the app wrapper. Note that there is no python binary in the app wrapper, only a symlink to one. The *only* substantial difference between the two scheme's is that in Jack's version argv[0] is (a) not the CFBundleExecutable (but still a file located in Contents/MacOS in the application bundle) and (b) sys.executable is automaticly a python interpreter. Another minor difference is that is harder to switch interpreters, but I'd tend to find this an advantage (but hey, I can change the main-bin-python.m file to not support NSUserDefaults making this a very minor difference). A minor variation on Jack's scheme would be to make the CFBundleExecutable a python script: #!/usr/bin/env python import sys print sys.executable This prints /usr/local/bin/python or /usr/bin/python on my system (depending on the value of PATH). You'd of course loose the advantage of linking with the needed frameworks. This would also make it harder to use an application-local Python installation, which is more problematic. > > The key difference is in the information contained within the > executable found within the app wrapper. In my solution, the > executable automatically carries the information about what frameworks > are used into the python interpreter by simply linking the custom > executable against the appropriate frameworks. This also allows the > developer to work directly with the Project Builder indices -- for > example, If I write "bundle = NSBundle.bundleWithPath_(path)", I can > command-double-click on the word NSBundle and Project Builder takes me > straight to the declaration for NSBundle (option-double-click displays > the documentation). I see the usefulness of using documentation from PB, but the week was probably slightly too long for me because I fail to see the usefullness of actually passing information about linked frameworks to the Python script: You still have to write a wrapper module for the frameworks, unless you intend to locate all classes by using objc.lookup_class. > >> I would think this works the same as Bills scheme, with the only >> exception that sys.executable points to a python interpreter, so >> something like system(sys.executable + " myscript.py") will work. > > Two solutions: > > (1) In Main.py (or __main__.py -- is that "more standard"?), set > sys.executable to whatever python interpreter the user has selected > (in my solution, that would mean reading the 'PythonBinPath' user > default in a similar fashion as the bootstrap executable). BuildApplication/BuildApplet in MacPython name the principle python file in the created application __main__.py, I suppose because the __main__ is the name of the 'toplevel' module and can therefore not be used for normal code (e.g. you cannot accidently overwrite a module when renaming the principle python file to __main__.py). > > (2) Make it such that the second invocation of sys.executable > [which points to the bootstrap binary in my app wrapper] simply calls > execve() with a command line that passes control to python along with > the arguments. I.e. put recursion protection on that executable. The > overhead of an extra execve() is trivial in comparison to the overhead > of a full blown GUI. This sounds pretty ugly. Actually implementing this correctly is hard, unless you implement the wrappper in python. Ronald |