How To Turn Python Scripts into Windows Executables
Categories:
how-to
python
exe
Python scripts are useful and easy - but only if you have the Python interpreter installed on your PC. If not, you can’t run them.
The first way around this that I used was called Py2Exe. It was a bit kludgy, but worked well enough at a time when there weren’t many options.
Despite my best efforts, time moved on and now we have more options for turning Python scripts into executables.
One good such option is PyInstaller, which seems to be very straightforward and has a (so far) great one-file packaging option. It produced a ~6MB exe
for a simple CLI script that does nothing, but who cares about disk usage these days anyway?
PyInstaller
PyInstaller seems to be a much more straightforward means of getting an
exe from a Python script. I didn’t have to muck around with any setup.py
files or options or anything, just a simple command line. And, I got a single
executable very easily.
The webpage for PyInstaller has a pretty straightfoward set of instructions
for installing and using PyInstaller. It got me up and running right away.
Installation
Here’s what I did and what happened:
Generating an Executable
After that, it’s a simple command-line to generate an executable:
This produced dist/pyCli.exe - one file only!
I’m kind of sad how easy that was.
Issues
With my version of PyInstaller Windows Defender flags it as a virus: Trojan:Win32/Wacatac.B!ml
This is a false alarm.
There’s a StackOverflow detailing the issue and fixes here.
Py2Exe - Deprecated
You probably shouldn’t even bother reading any of this, but it’s retained here for completeness. Also, maybe it’ll be useful someday. Who knows.
It’s worth noting that Py2Exe only works on Windows with Windows Python - not Cygwin Python.
Installation
You’ll need Python 2.7 for Windows installed before you can do install Py2Exe.
Installation is as simple as opening a command prompt and typing:
pip install py2exe
Alternately, you can go online and download it form SourceForge and then use the installer to install it.
Usage
First, you need a script to turn into an executable:
Well, that was easy. I’m going to store that script in a subdirectory of my project directory called ‘src’, so it’ll be at the relative path ‘src/helloWorld.py’.
This isn’t the only script you need. You’ll also need a setup.py script which has content that looks like this:
This script acts as a wrapper which allows Py2Exe to turn your script into an executable.
On the command line, you can generate the executable by navigating to the project directory and typing:
python setup.py py2exe
This produces a lot of output on the console, but more importantly will produce two directories: build and dist.
build contains temporary and leftover files used in the build. I’ve had no problem deleting it after a build. The dist folder contains everything your EXE needs to operate. The upshot is that if you want to move the EXE to another system, you need to copy everything in the dist folder to the new system and keep the directory structure in that folder intact. The main output of this process is the dist/helloWorld.exe file: the executable name matches the name of the Python script.
Once you run that executable, you’ll get the output you expect:
Hello World!
Generating a Single Executable File
Normally, when using Py2Exe, it will generate a big directory of miscellaneous files that are kinda messy alongside the executable you want.
There’s a way you can slim it all down to just one executable file.
This site discusses the options that you can pass to py2exe when you invoke it. The script that generates a single executable is here:
Issues
Missing Modules
I have more complex scripts that I want to turn into executables. These scripts import Python files that are present in the same directory. Py2Exe cannot seem to find these files and include them into the executable which means that the EXE will not work. The way to fix this is to alter the system path from within the setup.py script to add the path to the modules you want to import. For example, if the files are in the src subdirectory of the project directory, then you can modify the setup.py script as follows:
Once done, the script finds all of my custom modules, imports them and the EXE runs fine.
Dropbox, Virus Scanners, and WinError 110
Sometimes, you’ll get an error like this:
This sort of error is caused by another program trying to access the files that py2exe is trying to access. Usually, this is an antivirus program or (in my case) Dropbox. I remedied this error by turning off Dropbox or by moving the folder outside of my Dropbox folder.