py2app – Create standalone Mac OS X applications with Python

在 Windows 是用 py2exe 把 python 變 standalone,  在  Mac 是用 py2app, 滿神奇的,Mac OS X原本就有內建 python 和 pip 還有已經有  py2app.



和 py2exe 一樣,要先來一個

直接下 py2applet –make-setup 會顯示:
-bash: py2applet: command not found



所以,使用完整路徑,就可以使用, ex:

/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/bin/py2applet –make-setup


有了 後,下指令:

python py2app -A


error: [Errno 1] Operation not permitted:


禁用 System Integrity Protection (SIP) 的圖文教學1:

禁用 System Integrity Protection (SIP) 的教學2:

After I upgraded my operating system to OS X EI Capitan (10.11.2), I got similar error when packaging my app using py2app:

*** creating application bundle: MyApp ***
error: [Errno 1] Operation not permitted: '/Users/jake/work/my-app/dist/'

I did some research and found a solution: 1) disable SIP; 2) remove restricted file flag on Python.framework. It worked for me.

Disable SIP

  1. Restart your Mac.
  2. Before OS X starts up, hold down Command+R and keep it held down until you see an Apple icon and a progress bar. Release. This boots you into Recovery.
  3. From the Utilities menu, select Terminal.
  4. At the prompt type the following:
    csrutil status
    csrutil disable

You can re-enable SIP by following the above steps, but using:

csrutil enable


Remove Restricted File Flag

sudo chflags -R norestricted /System/Library/Frameworks/Python.framework

As it’s mentioned in


不想禁用 SIP, 可以改用 virtualenv

Creating standalone Mac OS X applications with Python and py2app


virtualenv 基礎教學:



pip install virtualenv


cd your_project_folder
virtualenv venv
. venv/bin/activate


要退出,就是下 deactivate 即可。

只有第1次需要下 virtualenv venv 之後要進去,就是 activiate 就進去了。

滿神奇的,可以不需要下 sudo 就可以透過 pip 安裝所有的程式。virtualenv 裡是乾淨的,所以所有第3方的 package 需要重新 pip install 一次。

先下 /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/bin/py2applet –make-setup


sudo python py2app -A

就成功了,原來  -A 是用來測試的。實際發行要拿掉 -A,  開始研究 sandwish 裡的參數:

This is a basic definition of the app:

from setuptools import setup

APP = ['']
OPTIONS = {'argv_emulation': True}

    options={'py2app': OPTIONS},

If your application uses some data files, like a JSON, text files or images, you should include them in DATA_FILES. For example:

DATA_FILES = ['testdata.json', 'picture.png']

Build the app for development and testing

py2app builds the standalone application based on the definition in

For testing and development, py2app provides an “alias mode”, which builds an app with symbolic links to the development files:

$ python py2app -A

This creates the following files and directories:

├── build
│   └── bdist.macosx-10.10-x86_64
│       └── python2.7-standalone
│           └── app
│               ├── Frameworks
│               ├── collect
│               ├── lib-dynload
│               └── temp
├── dist
│   └──
│       └── Contents
│           ├── Info.plist
│           ├── MacOS
│           │   ├── Sandwich
│           │   └── python -> /Users/chris/Projects/chris/python-gui/tkinter/env/bin/../bin/python
│           ├── PkgInfo
│           └── Resources
│               ├──
│               ├──
│               ├── lib
│               │   └── python2.7
│               │       ├── config -> /Users/chris/Projects/chris/python-gui/tkinter/env/bin/../lib/python2.7/config
│               │       └── site.pyc -> ../../site.pyc
│               ├──
│               └── site.pyc

This is not a standalone application, and the applications built in alias mode are not portable to other machines!

The app built with alias mode simply references the original code files, so any changes you make to the original file are instantly available on the next app start.

The resulting development app in dist/ can be opened just like any other .app with the Finder or the open command ($ open dist/ To run your application directly from the Terminal you can just run:

$ ./dist/

Building for deployment

When everything is tested you can produce a build for deployment with a calling python py2app. Make sure that any old build and dist directories are removed:

$ rm -rf build dist
$ python py2app

This will assemble your application as dist/ Since this application is self-contained, you will have to run the py2app command again any time you change any source code, data files, options, etc.

The original py2app has a bug which would display “AttributeError: 'ModuleGraph' object has no attribute 'scan_code'” or load_module. If you encounter this error, take a look at this StackOverflow thread or use my fork of py2app.

The easiest way to wrap your application up for distribution at this point is simply to right-click the application from Finder and choose “Create Archive”.

Adding an icon

Simply add "iconfile": "youricon.icns" to the OPTIONS dict:

from setuptools import setup

APP = ['']
    'argv_emulation': True,
    'iconfile': 'app.icns'

    options={'py2app': OPTIONS},

You can find free icons in icns format around the web (eg. on IconFinder or freepik).

Advanced app settings

You can tweak the application information and behaviour with modifications to the Info.plist. The most complete reference for the keys available is Apple’s Runtime Configuration Guidelines.

Here is an example with more modifications:

# -*- coding: utf-8 -*-
from setuptools import setup

APP = ['']
APP_NAME = "SuperSandwich"

    'argv_emulation': True,
    'iconfile': 'app.icns',
    'plist': {
        'CFBundleName': APP_NAME,
        'CFBundleDisplayName': APP_NAME,
        'CFBundleGetInfoString': "Making Sandwiches",
        'CFBundleIdentifier': "com.metachris.osx.sandwich",
        'CFBundleVersion': "0.1.0",
        'CFBundleShortVersionString': "0.1.0",
        'NSHumanReadableCopyright': u"Copyright © 2015, Chris Hager, All Rights Reserved"

    options={'py2app': OPTIONS},



發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *