Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can executables made with py2app include other terminal scripts and run them?

So I have a nice python app for OS X that is working great. It runs an external terminal script and I would like to include that in with my python app. Ideally, I'd be able to run py2app and have this script bundled up with it into the executable and then be able to include it and run it in the python portion of my code. Is this possible?

Thanks in advance!

Extra Edit: The script that I am using is compiled. I can't just look inside and paste it.

like image 298
Mizmor Avatar asked Jul 06 '12 21:07

Mizmor


1 Answers

See http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html#option-reference and look at the --resources parameter. For example:

python setup.py py2app --resources foo

If this were a shell script, that would be a perfectly valid thing to do. For a binary executable, it's a bit more hacky. First, p2app's documentation clearly says "not for code!". Second, the OS X documentation says not to put executables in the Resources directory. The main reason for this is code signing: the default settings "seal" everything in Resources as part of the main app's signature, but separate executables are not supposed to be sealed that way, they're supposed to be signed separately.

However, all that being said, it will still work. Except that it probably won't end up with +x permissions, so after your py2app step, you'll have to "chmod +x MyApp.app/Contents/Resources/foo" to make it runnable.

You can also use the distutils package_data, data_files, and/or MANIFEST stuff to add arbitrary files with arbitrary relative paths, which might be a better solution, but it's more complicated.

Either way, in your script, you should use the bundle-related path, which you can easily access via PyObjC. Given that you're using a PowerPC executable, you may need so much backward compatibility that you can't rely on that, in which case you may have to make do with just "../Resources/foo", but otherwise, it looks like this:

import Foundation
# ...
bundle = Foundation.NSBundle.mainBundle()
path = bundle.pathForResource_ofType_('foo', None)

You can then launch it with NSTask, or subprocess,Popen, os.system, etc.

like image 97
abarnert Avatar answered Oct 14 '22 10:10

abarnert