Why does a py2app .app take longer to launch than the same python program?-Collection of common programming errors
I’m not sure my question / title is phrased quite right. I’m working on OSX 10.6 and python 2.7.1. I’ve used setuptools and py2app to create a .app, which I can run from the finder or from the terminal using open.
One of my goals for the program is to launch quickly.
When I go into the build folder and run the python program directly using python, my window pops up right away. In less than 1 second. It’s pretty consistent. But when I go into the dist folder and run the .app (either from the finder or with open), there is a several second pause before the window shows up. About 4 to 5 seconds, pretty consistently.
I thought maybe it had something to do with open trying to find a document or something, so I tried this:
open -a testrun.app ""
..and sure enough, the window pops right away!
Is there something I need to do in the setup.py or some place to tell it that this is not a document-oriented program?
A little more detail –
I’m working on OSX 10.6.8 with Python 2.7.1 (as the system python). I’ve tried some minor variations on this (2.6 with python_select, 2.7.3 in a virtualenv..), but so far, it hasn’t made any difference.
I created a simple .dylib (in objective-c) which exports a function that opens a window using cocoa. I created a very simple python extension module (in c) that has a function in it that calls the .dylib function.
(My plan is to create a platform-specific shared/dynamic library in a platform language for gui calls and related platform-specific calls, and a cross-platform c library that uses that, then create high level language extension modules that make the c library available to those languages.)
I wrote a very simple python program that calls the c function. I wrote a setup.py that builds everything and uses py2app to create a .app.
Here’s the build script for the .dylib:
gcc -framework Cocoa -dynamiclib -x objective-c testlib.objc -current_version 1.0 -compatibility_version 1.0 -o libTestlib.1.dylib -arch i386 -arch x86_64
Here’s the setup.py:
from setuptools import setup, Extension
APP = ['testrun.py']
DATA_FILES = []
OPTIONS = {
'argv_emulation': True,
'frameworks': ['/Users/shavais/scratch/objc/libTestlib.1.dylib']
}
module1 = Extension(
'demo',
sources = ['demo.c'],
libraries = ['Testlib.1'],
library_file_directories = ['/Users/shavais/scratch/objc']
)
setup(
name = 'testrun',
description = 'This is a testrun package',
app = APP,
data_files = DATA_FILES,
options = {'py2app': OPTIONS},
setup_requires = ['py2app'],
version = '1.0',
py_modules = ['testrun'],
ext_modules = [module1]
)
-
I don’t know about py2app on Mac (never used it) but if it works similar to http://www.pyinstaller.org/, then the binary has to unpack the python runtime, your program and all the modules into memory. This takes time.
-
Set “argv_emulation” to False unless you actually need that functionality (that is, unless you want to be able to drop files on your application bundle and then have those file names as arguments in sys.argv).
“Argv_emulation” is a hack for converting AppleEvents that request opening files into extra arguments in sys.argv. To do this the emulation code spins up an event loop and waits for those open events or a timeout. You are likely running into that timeout.