py2exe

Convert python scripts into standalone windows programs

Copyright (C) 2001, Thomas Heller

Abstract

py2exe is a distutils extension to convert python scripts into executable windows programs, which are able to run without requiring a python installation.

Status

py2exe is reaching a stable state.
It has been used to create wxPython, Tkinter, Pmw, PyGTK, pygame, win32com client and other standalone programs.

I would like to thank everyone who tried out this little utility and gave me feedback.

py2exe is distributed under an open-source license.

News

2001/04/05
Release 0.2.5: Full Tkinter support, py2exe automatically copies your tcl/tk installation into the dist directory if your script uses Tkinter.
Does no longer copy system dlls, which should prevent strange errors when the final executable is run on other systems.
The binary distributions contain an uninstaller, py2exe can be uninstalled from the Control Panel applet.
2001/02/13
Release 0.2.3: py2exe now can change the icon in the resulting executable, see the --icon command line flag.
2001/02/08
Release 0.2.2: New command line flags to fine-tune the building process, several bugfixes. py2exe can now copy additional files into the dist directory. py2exe has been used to create a standalone COM server exe-file, although this is currently in a very early stage.
2001/02/02
Release 0.2.1: --includes now understands hierachical (dotted) module names, fixed the AttributeError: __ispkg__ bug, which prevented running the built executables in rare cases.
2001/01/31
Release 0.2.0 finds needed dlls automatically, has new command-line options, can build programs containing modules imported via the registry (pythoncom, pywintypes).
2001/01/24
Release 0.1.1 fixes the bugs of the first beta-release and should work as advertised.
2001/01/19
First public beta-version released and announced on comp.lang.python.

Using py2exe

Assuming you have a python script myscript.py which you want to convert into an executable windows program, able to run even on systems without a python installation. If you don't already have written a distutils setup-script, write one, and insert the statement import py2exe before calling the setup function.

Here's a simple one:


         # setup.py
         from distutils.core import setup
         import py2exe

         setup(name="myscript",
               scripts=["myscript.py"],
         )

Running:


        python setup.py py2exe --help

will display all available command-line flags for the py2exe command.

Now you can call the setup script like this:


         python setup.py py2exe

and a sub-directory dist\myscript will be created, containing the files myscript.exe and python20.dll. If your script uses compiled c-extension modules, they will be copied here as well, also all dlls needed at runtime.

These files include everything that is needed for your program, even if the target computer doesn't have python installed.

Specifying additional files

Some applications need additional files at runtime, this maybe configuration files, fonts, bitmaps, whatever.

py2exe can copy these files into subdirectories of dist\myscript if they are specified in the setup script with the data_files option. data_files should contain a sequence of (target-dir, files) tuples, where files is a sequence of files to be copied.

Here's an example:


         # setup.py
         from distutils.core import setup
         import glob
         import py2exe

         setup(name="myscript",
               scripts=["myscript.py"],
               data_files=[("bitmaps",
                            ["bm/large.gif", "bm/small.gif"]),
                           ("fonts",
                            glob("fonts\\*.fnt"))],
         )

This would create a subdirectory bitmaps in dist\myscript, containing the two bitmaps, and a subdirectory fonts, containing all the *.fnt files.

How does it work?

py2exe uses python's modulefinder to load your script and find all python and extension modules needed to run it. Pure python modules are compiled into .pyc or .pyo files in a temporary directory. Compiled extension modules (.pyd) are also found and parsed for binary dependencies.

A zip-compatible archive is built, containing all files from this directory as well as your script, and appended to a custom python interpreter supplied with py2exe.

Running the resulting program, now called myscript.exe, will install an import hook so that the modules needed can be imported from the zip-archive, and your script will be started.

In simple cases, only pythonxx.dll is needed in addition to myscript.exe. If, however, your script needs extension modules, unfortunately those cannot be included or imported from the zip-archive, so they are needed as separate files (and are copied into the dist\myscript directory).

Attention: py2exe tries to track down all binary dependencies for all pyd's and dll's copied to the dist directory recursively, and copies all these dependend files into the dist directory. py2exe has a build in list of some system dlls which are not copied, but this list can never be complete.

Reference

Command line flags for the py2exe command (run python setup.py py2exe --help for an up-to-date list):

--debug or -g
Create runtime with debugging information. Default is to create a release runtime binary. Note that for debug builds, all extension modules must be available in debug versions.
--optimize or -O 0|1|2
optimization level: -O1 for "python -O", -O2 for "python -OO" and -O0 to disable (default: -O0)
--dist-dir or -d directory
directory to put the final files in
--force or -f
force a rebuild of everything
--keep-temp or -k
keep the pseudo installation tree around after creating the distribution files
--console or -c
build a console application, similar to running the script with python.exe. The default is to create a console application if the script has the extension .py, a console-less GUI application if the script has the extension .pyw
--windows or -w
build a windows application, similar to running the script with pythonw.exe
--excludes or -e list
comma separated list of modules to exclude
--includes or -i list
comma separated list of modules to include. Note that includes overrides excludes.
--packages or -p list
comma separated list of packages to include.
--force-imports list
comma separated list of modules to inject into sys.modules before running the script.
--icon
ico-file
This options allows to change the icon in the exe-file. You can only use this flag if you run the build process under Windows NT or Windows 2000.

The following flags are planned but not yet implemented:

--unbuffered or -u
unbuffered binary stdout and stderr
--unicode or -U
treat string literals as unicode

Note that you can supply these options to py2exe on the command line, or put them into a setup configuration file setup.cfg.

Details about configuration files are available in the distutils documentation.

Requirements for using py2exe

Python 1.5

Distutils is required. You can download and install the latest release from python.org.

To build the zip-compatible archive py2exe needs a zip.exe utility somewhere on the PATH, or Jim Ahlstrom's zipfile-module.

Python 1.6 and later

Everything is already included in the python distribution.

Download and project information

Older versions are available, but you have to guess the URL's.

Binaries (windows installer)

The binary distributions now contain an uninstaller, you can uninstall py2exe from the Control Panel applet (but you won't ;-).

For Python 2.0: py2exe-0.2.5.win32-py2.0.exe.

For Python 1.5: py2exe-0.2.5.win32-py1.5.exe.

A Python 2.1 version will be published as soon as the final release is out.

Source code

Download py2exe-0.2.5.zip.

Project hosting

The project is hosted at http://sourceforge.net/projects/py2exe/.

Problems

Import errors

Python's modulefinder does a pretty good job, but there are some cases in which it does not track dependencies correctly and you would have to use command-line flags to fine-tune the building process.

Modulefinder scans the byte-code for IMPORT instructions. It cannot, however, find calls to the __import__ built-in function, find import statements constructed on the fly and executed with 'exec'. In case you get ImportErrors when you run the built executable, simply rebuild specifying the missing modules with the --includes flag.

A second problem are extension modules using the PyImport_ImportModule function to import other python modules (instead of PyImport_Import). This function does not use the import-hook we are installing, so the import will fail even if the required module is available. The generated executable will usually fail with an error message like Fatal Python Error: couldn't import 'module', or sometimes even crash.

The solution to this is to rebuild with the --force-imports flag. This will ensure that these modules are injected into sys.modules before your scripts starts, and so PyImport_ImportModule can find them.

Future plans

More aggressive strategy to find modules needed: This will (hopefully) obsolete some of the more difficult command line flags, also less warnings should be printed when building.

Clean up and document the environment in which the script is run, provide a way to add hooks so that the build executable can import modules from the file system (may be usefull for extensible applications).

Allow local (dll) and inproc (exe) COM servers to be built.

Provide a way to require even less files: provide more custom prebuilt interpreters, so that eventually everything can be packed into a single file (which can be run without unpacking anything).

Related work

Fredrik Lundh's squeeze is "a simple utility which compiles your Python program into a bytecode package, allowing you do distribute Python programs as one or two files".

Christian Tismer's sqfreeze is based on an early version of squeeze.

Gordon McMillan's installer is similar to py2exe.


SourceForge Logo