109

I'm currently trying to make an executable using py2exe. I use Python 3.6. The script I'm using imports openpyxl and pptx and runs fine when I use Pycharm or run the script using the command window.

The output produces the error:

IndexError: tuple index out of range

Below you can find the cmd output:

C:\Python36>python setup.py py2exe
running py2exe
Traceback (most recent call last):
  File "setup.py", line 4, in <module>
    setup(console=['Storybookmaker.py'])
  File "C:\Python36\lib\distutils\core.py", line 148, in setup
    dist.run_commands()
  File "C:\Python36\lib\distutils\dist.py", line 955, in run_commands
    self.run_command(cmd)
  File "C:\Python36\lib\distutils\dist.py", line 974, in run_command
    cmd_obj.run()
  File "C:\Python36\lib\site-packages\py2exe\distutils_buildexe.py", line 188, in run
    self._run()
  File "C:\Python36\lib\site-packages\py2exe\distutils_buildexe.py", line 267, in _run
    builder.analyze()
  File "C:\Python36\lib\site-packages\py2exe\runtime.py", line 160, in analyze
    self.mf.import_hook(modname)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 120, in import_hook
    module = self._gcd_import(name)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 274, in _gcd_import
    return self._find_and_load(name)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 357, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 388, in _scan_code
    for what, args in self._scan_opcodes(code):
  File "C:\Python36\lib\site-packages\py2exe\mf3.py", line 417, in _scan_opcodes
    yield "store", (names[oparg],)
IndexError: tuple index out of range

C:\Python36>

What causes the IndexError?

Edit: here is the setup.py file:

from distutils.core import setup
import py2exe

setup(console=['Storybookmaker.py'])
martineau
  • 119,623
  • 25
  • 170
  • 301
Dennis
  • 1,201
  • 2
  • 8
  • 10
  • 2
    can you show us your `setup.py` file? because the problem is there and not in `py2exe` which works fine. – Jean-François Fabre Jan 10 '17 at 21:46
  • 1
    Hi Jean-Francois, I've added the file in the original post. Thanks in advance! – Dennis Jan 10 '17 at 21:58
  • 1
    is the `Storybookmaker.py` file in the same directory as `setup.py` ? you could try `setup(console=[os.path.join(os.path.dirname(__file__,'Storybookmaker.py')])` to be sure to locate the file. – Jean-François Fabre Jan 10 '17 at 22:06
  • 1
    @Jean-FrancoisFabre Both setup.py and Storybookmaker.py in the C:\Python36 folder, so that should not matter but I tried it anyway with your code. It get the same IndexError. Any other thoughts? – Dennis Jan 11 '17 at 07:21
  • @Dennis: `py2exe` is back. See my updated answer (and please give it a check if it solves your problem). – ShadowRanger Nov 17 '20 at 18:20

6 Answers6

101

Update (2020-11-17): py2exe LIVES!!!

Apparently my pessimism a year ago (see "Update" at bottom of original post) was unwarranted. py2exe released new versions in October and November of 2020, supporting 3.5-3.8 in 0.10.0.2 and adding 3.9 support in 0.10.1.0 (dropping support for 3.4 and earlier). As long as you upgrade to an appropriate py2exe version (0.10 and higher), this problem should not occur.

Further update (2022-11-09): It looks like py2exe is staying up to date with the latest releases of CPython now (e.g. they released 0.13.0.0, a 3.11 compatible py2exe, within two weeks of CPython 3.11.0 itself being released) so it looks like you can rely on continuing support for the time being. They seem to be supporting 4-5 minor releases of CPython for any given release (the first release with 3.9 support dropped support for 3.4 and earlier, and the latest release that added support for 3.11 dropped 3.7 support).


Original Answer before py2exe 0.10 release

Python 3.6 completely redesigned the bytecode for CPython (it's not a "byte" code at all anymore, it's a wordcode, where all opcodes are two bytes wide instead of 1-3).

The failure you're seeing occurs in py2exe opcode parsing code, which, given the most recent posted version of py2exe only claims support for 3.3 and 3.4, could not possibly have knowledge of, or support for, the new wordcode opcodes; they hadn't even been conceived of at the time py2exe was last updated. The bytecode often changes in small ways from version to version that could break even Python 3.5 (given only 3.3 and 3.4 support is claimed explicitly), but 3.6 is 100% guaranteed to fail.

Update: At this point (November 2019), it's been over five years since the last py2exe release, and by the beginning of 2020 (when Python 2 support lapses completely), it will not run on any supported version of Python (3.4 is already out of support). I think it's safe to say the project is abandoned; find other options, e.g. cx_Freeze or PyInstaller.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • 4
    So isn't there any alternatives? – Ghasem Nov 21 '17 at 17:28
  • @AlexJolig: There are, though I haven't checked if they're all Python 3.6 compatible. I'm aware of PyInstaller and cx_Freeze; there may be others. – ShadowRanger Nov 22 '17 at 00:53
  • 8
    I've tested `cx_freeze`. It's compatible with python3.6 but it can't create a single exe file. The problem with `Pyinstaller` is you can't create x86 exe file via a x64 os – Ghasem Nov 22 '17 at 03:49
  • Thanks for this info. Must say I'm mildly surprised this isn't really documented up front somewhere. Even the py2exe description merely says `Python 3.3 and later are supported`. Sure, in hindsight it's probably a bit naive to expect something so old to work but when you're a beginner in this space, there's enough newbie confounds to deal with. – fostandy Mar 26 '20 at 01:00
  • @fostandy: See updated answer. Looks like they finally brought it up to date (dropping support for 3.4 and earlier, adding support for 3.5 through 3.9). – ShadowRanger Nov 17 '20 at 18:20
  • Version 0.10.1.0 has dropped support for 3.5 – recurseuntilfor Mar 11 '21 at 10:41
41

Update (2021-11-3): As @ShadowRanger has said in his update py2exe lives. Also Version 0.10.1.0 has dropped support for python 3.5 or less PyInstaller or cx_Freeze can be used as an alternative.


Original Answer

The solution I used was to use PyInstaller as an alternative because Py2Exe stopped development at python 3.4 and will not work with newer versions.

C:/>pip install pyinstaller
C:/>pyinstaller yourprogram.py

This will create a subdirectory called dist with the yourprogram.exe contained in a folder called yourprogram.

Use -F to place all generated files in one executable file.

C:/>pyinstaller -F yourprogram

Use can use -w to if you want to remove console display for GUI's.

C:/>pyinstaller -w yourprogram.py

Putting it all togerther.

C:/>pyinstaller -w -F yourprogram.py

Read more about PyInstaller here.

Python version 3.7.3.

recurseuntilfor
  • 2,293
  • 1
  • 12
  • 17
  • 2
    If I run the program on other computers, I get "No module found erros.." – yarin Cohen Aug 28 '19 at 17:54
  • thanks for your solution about pyinstaller. successfully manage to create a standalone project using the minggw64 python3.8.2 release and gtk on windows 10 : gi, gtk, dlls..everything is here in the dist folder using a simple "$ pyinstaller yourprogram" command in the minggw64 shell. pyinstaller + cython looks like a nice combo. – jerome Feb 29 '20 at 18:35
10

I had same problem, as workaround I used cx_freeze. My app is based on wxPython, windows 10, python 3.6, cx_freeze 5.5.1

This is the setup file that I used and I got msi file on dist folder.

#setup.py
import sys, os
from cx_Freeze import setup, Executable

__version__ = "1.1.0"

include_files = ['logging.ini', 'config.ini', 'running.png']
excludes = ["tkinter"]
packages = ["os", "idna", "requests","json","base64","pyodbc"]

setup(
    name = "appname",
    description='App Description',
    version=__version__,
    options = {"build_exe": {
    'packages': packages,
    'include_files': include_files,
    'excludes': excludes,
    'include_msvcr': True,
}},
executables = [Executable("b2b_conn.py",base="Win32GUI")]
)`

then python setup.py bdist_msi

Ezequiel Alanis
  • 451
  • 5
  • 12
  • 4
    Like you, I used cx_freeze to create an executable because this was compatible with my python version and easier to use. Thank you for sharing your setup file so that people can use this as an example. – Dennis Jan 17 '18 at 08:50
  • If I have `from PyQt5 import QtGui` how do I enter it in `packages`? Only `PyQt5` or only `QtGui` or both? – Hrvoje T May 24 '18 at 06:20
  • Hrvoje T, I've included the whole `PyQt5`. – Taras Mykhalchuk Jun 27 '18 at 05:57
7

I tried a workaround, by installing Python 3.4.3:

C:\socket> c:\Python34\python.exe setup.py py2exe

1) enter in your script folder

2) deactivate any antivirus that you have (weird thing, know by another SO question xD)

3) call the python 3.4.3 interpreter by his absolute path, in my case, i've installed in:

C:\Python34

4) execute the command

C:\Python34\python.exe setup.py py2exe
evandrix
  • 6,041
  • 4
  • 27
  • 38
  • I tried to do the same thing with Python 3.5 but got stuck at installing py2exe because pip needs a newer version, I get an error. `You are using pip version 8.1.1, however version 9.0.1 is available. You should consider upgrading via the 'python -m pip install --upgrade pip' command.` When I try to upgrade pip, I get the same error! – Dennis Jan 11 '17 at 07:26
  • As i see, you have 2 choices: `1) Try with Python 3.4.3, this one i have already tested.` `2) Identify which python you have, when you type at console 'python', what version says?`may be you have 2 python and need to specify which one you want update. – Ricardo Martínez Jan 12 '17 at 02:40
  • by the way, @Dennis – Ricardo Martínez Jan 12 '17 at 02:48
  • Martinez the version now says 3.5 instead of 3.6. I specified the path to 3.5 and the pip 8.1.1 is only installed for 3.5, because 3.6 already has 9.0.1. I will your try you advice with multiple versions. – Dennis Jan 12 '17 at 07:31
  • Sorry for the delay, enter in your Python Folder and run 'python -m pip install --upgrade pip', and update your Python 3.5 Pip – Ricardo Martínez Jan 26 '17 at 02:42
  • Martinez Thanks for you help. Eventually I decided to stick with my 3.6 version of python. I tried `cx_freeze` for compiling my code into a .exe and it works like a charm! – Dennis Jan 27 '17 at 08:17
  • thanks for the edit @evandrix, maybe the title of the edit is not necessary. – Ricardo Martínez Mar 30 '20 at 09:45
7

I've had success with a Python 3.6 program using the fork of py2exe at https://github.com/albertosottile/py2exe.

Rasjid Wilcox
  • 659
  • 7
  • 11
0

At time of writing, the latest python-version is 3.8 and py2exe works until python-3.4. pyinstaller works until python-3.7. Using pyinstaller's command-line options (like --onefile to make a standalone executable) is easier than coding options into py2exe's setup.py file...Especially since the setup.py files that worked for python2 don't work for python3. Another useful pyinstaller option is --noconsole to make the executable start as a background process.

So, a time-less solution is using the python-module virtualenv. Then you can create your executable without uninstalling your current python-version along with all its modules, to replace it with an older version.

C:\Users\jf>pip install virtualenv
C:\Users\jf>python -m virtualenv box37 -p c:\users\jf\python37\python.exe
C:\Users\jf>C:\Users\jf\box37\Scripts\activate
(box37) C:\Users\jf>
(box37) C:\Users\jf>pip install pyinstaller
(box37) C:\Users\jf>pyinstaller --onefile test.py
(box37) C:\Users\jf>deactivate
C:\Users\jf>

The command-line option -p c:\path\to\target\python\interpreter, is case-sensitive! For pyinstaller use the path you downloaded python-3.7 to (py2exe the path to 3.4).

When created the virtual env. generates a directory with your given name (e.g. box37) in the working directory. Executing the script \Script\activate inside this directory enters the virutal env. - notice (box37) appearing before my prompt.

Inside a python virtual env. pip is used to install modules that won't be accesible to python outside - notice it has its own \Lib\site-packages directory. Hence what makes virtualenv a perfect test-set-up module - if you screw up, just delete the (e.g. box37) directory.

Download Python 3.7, Windows x86-64 executable installer. Download Python 3.4, Windows x86-64 MSI installer.