IndexError: indeks krotki poza zakresem podczas korzystania z py2exe

106

Obecnie próbuję utworzyć plik wykonywalny przy użyciu py2exe. Używam Pythona 3.6. Skrypt, którego używam, importuje openpyxli pptxdziała dobrze, gdy używam Pycharm lub uruchamiam skrypt za pomocą okna poleceń.

Dane wyjściowe generują błąd:

IndexError: tuple index out of range

Poniżej można znaleźć cmdwynik:

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>

Co powoduje IndexError?

Edycja: oto setup.pyplik:

from distutils.core import setup
import py2exe

setup(console=['Storybookmaker.py'])
Dennis
źródło
2
czy możesz pokazać nam swój setup.pyplik? ponieważ problem istnieje i nie py2exedziała dobrze.
Jean-François Fabre
1
Cześć Jean-Francois, dodałem plik w oryginalnym poście. Z góry dziękuję!
Dennis
1
czy Storybookmaker.pyplik znajduje się w tym samym katalogu co setup.py? możesz spróbować setup(console=[os.path.join(os.path.dirname(__file__,'Storybookmaker.py')])zlokalizować plik.
Jean-François Fabre
1
@ Jean-FrancoisFabre Zarówno setup.py, jak i Storybookmaker.py w folderze C: \ Python36, więc to nie powinno mieć znaczenia, ale i tak wypróbowałem to z twoim kodem. Otrzymuje ten sam błąd IndexError. Jakieś inne myśli?
Dennis,

Odpowiedzi:

96

Python 3.6 całkowicie przeprojektował kod bajtowy dla CPythona (nie jest to już kod „bajtowy”, jest to kod słowny, w którym wszystkie rozkazy mają szerokość dwóch bajtów zamiast 1-3).

py2exeBłąd, który widzisz, występuje w kodzie parsującym opcode, który, biorąc pod uwagę najnowszą opublikowaną wersję, która py2exetwierdzi, że obsługuje tylko wersje 3.3 i 3.4, prawdopodobnie nie może mieć wiedzy lub wsparcia dla nowych rozkazów kodu słownego; nie zostały one nawet poczęte w tym czasie, py2exezostały ostatnio zaktualizowane. Kod bajtowy często zmienia się w niewielkim stopniu od wersji do wersji, co może zepsuć nawet Python 3.5 (podane tylko wsparcie 3.3 i 3.4 jest wyraźnie deklarowane), ale 3.6 gwarantuje 100% niepowodzenie.

Aktualizacja: w tym momencie (listopad 2019 r.) Minęło ponad pięć lat od ostatniej py2exewersji , a do początku 2020 r. (Kiedy obsługa Python 2 całkowicie wygaśnie), nie będzie działać na żadnej obsługiwanej wersji Pythona (3.4 już jest wsparcia). Myślę, że można bezpiecznie powiedzieć, że projekt został porzucony; znajdź inne opcje, np . cx_Freezelub PyInstaller.

ShadowRanger
źródło
4
Czy nie ma więc alternatywy?
Alex Jolig
@AlexJolig: Są, chociaż nie sprawdziłem, czy wszystkie są zgodne z Pythonem 3.6. Jestem świadomy PyInstaller i cx_Freeze; mogą być inni.
ShadowRanger
8
Testowałem cx_freeze. Jest kompatybilny z pythonem 3.6, ale nie może utworzyć pojedynczego pliku exe. Problemem Pyinstallerjest nie można utworzyć plik exe x86 poprzez OS x64
Alex Jolig
Dzięki za te informacje. Muszę powiedzieć, że jestem lekko zaskoczony, że nie jest to gdzieś udokumentowane. Nawet opis py2exe tylko mówi Python 3.3 and later are supported. Jasne, z perspektywy czasu prawdopodobnie naiwne jest oczekiwanie, że coś tak starego zadziała, ale kiedy jesteś początkującym w tej dziedzinie, jest wystarczająco dużo zamieszania dla początkujących, z którymi możesz sobie poradzić.
fostandy
39

Rozwiązaniem, którego użyłem, było użycie PyInstaller jako alternatywy, ponieważ Py2Exe zatrzymał rozwój w Pythonie 3.4 i nie będzie działać z nowszymi wersjami.

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

Spowoduje to utworzenie podkatalogu o nazwie dist z plikiem yourprogram.exe zawartym w folderze o nazwie yourprogram.

Użyj -F, aby umieścić wszystkie wygenerowane pliki w jednym pliku wykonywalnym.

C:/>pyinstaller -F yourprogram

Użyj opcji -w to, jeśli chcesz usunąć wyświetlanie konsoli dla GUI.

C:/>pyinstaller -w yourprogram.py

Łącząc to wszystko razem.

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

Przeczytaj więcej o PyInstaller tutaj .

Python w wersji 3.7.3.

recurseuntilfor
źródło
2
Jeśli uruchomię program na innych komputerach, otrzymam komunikat „No module found erros ..”
yarin Cohen
dziękuję za rozwiązanie dotyczące pyinstaller. pomyślnie udało się stworzyć samodzielny projekt przy użyciu wydania minggw64 python3.8.2 i gtk w systemie Windows 10: gi, gtk, dlls… wszystko jest tutaj w folderze dist za pomocą prostego polecenia „$ pyinstaller yourprogram” w powłoce minggw64. pyinstaller + cython wygląda na niezłą kombinację.
jerome
10

Miałem ten sam problem, jako obejście użyłem cx_freeze. Moja aplikacja jest oparta na wxPythonie, Windows 10, Pythonie 3.6, cx_freeze 5.5.1

To jest plik instalacyjny, którego użyłem i mam plik msi w folderze dist.

#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")]
)`

następnie python setup.py bdist_msi

Ezequiel Alanís
źródło
4
Podobnie jak ty, użyłem cx_freeze do stworzenia pliku wykonywalnego, ponieważ był on zgodny z moją wersją Pythona i łatwiejszy w użyciu. Dziękujemy za udostępnienie pliku instalacyjnego, aby ludzie mogli użyć tego jako przykładu.
Dennis
Jeśli mam, from PyQt5 import QtGuijak mam to wpisać packages? Tylko PyQt5czy tylko QtGuiczy oba?
Hrvoje T
Hrvoje T, załączyłem całość PyQt5.
Taras Mykhalchuk
7

Próbowałem obejść ten problem, instalując Python 3.4.3:

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

1) wejdź do folderu skryptów

2) dezaktywuj dowolny program antywirusowy, który posiadasz (dziwna rzecz, wiem po innym pytaniu SO xD)

3) wywołaj interpreter języka Python 3.4.3 według jego ścieżki absolutnej, w moim przypadku zainstalowałem w:

C:\Python34

4) wykonać polecenie

C:\Python34\python.exe setup.py py2exe
Ricardo Martínez
źródło
Próbowałem zrobić to samo z Pythonem 3.5, ale utknąłem przy instalacji py2exe, ponieważ pip potrzebuje nowszej wersji, pojawia się błąd. 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.Kiedy próbuję zaktualizować pip, pojawia się ten sam błąd!
Dennis,
Jak widzę, masz 2 możliwości: 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?być może masz 2 pythony i musisz określić, który z nich chcesz zaktualizować.
Ricardo Martínez
przy okazji, @Dennis
Ricardo Martínez
Martinez, wersja mówi teraz 3.5 zamiast 3.6. Podałem ścieżkę do 3.5 i pip 8.1.1 jest zainstalowany tylko dla 3.5, ponieważ 3.6 ma już 9.0.1. Spróbuję ci porady z wieloma wersjami.
Dennis
Przepraszamy za opóźnienie, wejdź do folderu Pythona i uruchom `` python -m pip install --upgrade pip '' i zaktualizuj Python 3.5 Pip
Ricardo Martínez