базовый pyinstaller на MacOS X


Я пытаюсь заставить pyinstaller работать с моим скриптом python, который терпит неудачу. Поэтому я попробовал очень простой скрипт:

#!/usr/bin/env python
from matplotlib.pyplot import *
from numpy import *
x=linspace(0,2*pi,200)
plot(x,sin(x))
show()

Но это также не удается с сообщением об ошибке ниже. Я на современном Горном Льве и использую enthought python, если это имеет значение. Я вызываю его с python pyinstaller.py --onefile ../testpyinst.py , когда нахожусь в каталоге pyinstaller и полный вывод здесь:

23 INFO: wrote xxxxxxxxxxxxxx/pyinstaller-2.0/testpyinst/testpyinst.spec
54 INFO: UPX is not available.
1263 INFO: checking Analysis
1337 INFO: checking PYZ
1350 INFO: checking PKG
1350 INFO: building because out00-PKG.toc missing or bad
1350 INFO: building PKG out00-PKG.pkg
Traceback (most recent call last):
  File "pyinstaller.py", line 91, in <module>
    main()
  File "pyinstaller.py", line 86, in main
    run_build(opts, spec_file)
  File "pyinstaller.py", line 50, in run_build
    PyInstaller.build.main(spec_file, **opts.__dict__)
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/build.py", line 1625, in main
    build(specfile, buildpath)
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/build.py", line 1582, in build
    execfile(spec)
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/testpyinst/testpyinst.spec", line 16, in <module>
    console=True )
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/build.py", line 987, in __init__
    crypt=self.crypt)
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/build.py", line 880, in __init__
    self.__postinit__()
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/build.py", line 315, in __postinit__
    self.assemble()
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/build.py", line 933, in assemble
    archive.build(self.name, mytoc)
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/loader/archive.py", line 202, in build
    self.save_toc(tocpos)
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/loader/carchive.py", line 250, in save_toc
    tocstr = self.toc.tobinary()
  File "xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/loader/carchive.py", line 79, in tobinary
    nmlen+entrylen, dpos, dlen, ulen, flag, typcd, nm+pad))
struct.error: argument for 's' must be a string
4 2

4 ответа:

Удалось ли вам построить что-нибудь с помощью pyinstaller? Я предлагаю вам написать более простой код, который не имеет внешних зависимостей,

print "Hello World!"

Или

f = open('test.txt','w')
f.write("Hello World!")
f.close()

Попробуйте импортировать стандартный библиотечный модуль, скажем math:

import math
x = 10.0
y = math.sqrt(x)
print "square_root({}) = {}".format(x,y)

Затем попробуйте использовать numpy, который просто печатает sin(x) вместо того, чтобы пытаться построить его.

from numpy import *
x = linspace(0,2*pi,20)
print sin(x)

Если это работает, возможно, вместо showв сюжете, попробуйте savefig и посмотрите, имеет ли ошибка какое-то отношение к попытке отобразить фигура.

from matplotlib.pyplot import *
from numpy import *
x=linspace(0,2*pi,200)
plot(x,sin(x))
savefig("/tmp/testfig.png")

Если это все еще не работает, это может быть проблемой с вашим бэкэндом matplotlib. Используйте более простой / стандартный вариант:

import matplotlib
matplotlib.use("Agg")
from matplotlib.pyplot import *
from numpy import *
x=linspace(0,2*pi,200)
plot(x,sin(x))
savefig("/tmp/testfig.png")

, что я сделал-это открыть этот файл xxxxxxxxxxxxxx/pyinstaller-2.0/PyInstaller/loader/carchive.py, и добавьте несколько print() после строки 79. И я обнаружил, что NM+pad не распознается как строка. Хотя это довольно странно. Я использую windows 7, print() показывает, что nm=kernel32 и pad = ''.

Теперь поговорим о моем временном решении:

rslt.append(struct.pack(self.ENTRYSTRUCT + repr(nmlen) + 's', nmlen + entrylen, dpos, dlen, ulen, flag, typcd, nm + pad))

- - - - изменить на- - - - - >

try:
    rslt.append(struct.pack(self.ENTRYSTRUCT + repr(nmlen) + 's', nmlen + entrylen, dpos, dlen, ulen, flag, typcd, nm + pad))
except:
    ss = str(nm + pad)
    rslt.append(struct.pack(self.ENTRYSTRUCT + repr(nmlen) + 's', nmlen + entrylen, dpos, dlen, ulen, flag, typcd, ss))

Не уверен, что это надежное решение, но оно работает в моем. Я верю, что вы можете использовать подобную технику, чтобы выяснить свою. Кстати, я использую pyinstaller2.1 + вместо python2.7.6. Команда является pyinstaller -F MyApp.py --hidden-import=scipy.special._ufuncs_cxx

Моя проблема была такой же, как описано в комментарии hxu; изменение

rslt.append(struct.pack(self.ENTRYSTRUCT + repr(nmlen) + 's', nmlen + entrylen, dpos, dlen, ulen, flag, typcd, nm + pad))

To

rslt.append(struct.pack(self.ENTRYSTRUCT + repr(nmlen) + 's', nmlen + entrylen, dpos, dlen, ulen, flag, typcd, nm.encode('utf8') + pad))

Работал на меня, потому что type (nm) был "unicode", в то время как type(pad) str.

У меня была похожая проблема с Win7 и Pythonxy. Мне пришлось отредактировать файл C:\Python27\Lib\site-packages\pyinstaller-2.1-py2.7.egg\PyInstaller\loader\pyi_carchive.py строки 84-85 и изменить nm + pad на str(nm + pad)

Оригинал:

rslt.append(struct.pack(self.ENTRYSTRUCT + repr(nmlen) + 's',nmlen + entrylen, dpos, dlen, ulen, flag, typcd, nm + pad))

Исправить:

rslt.append(struct.pack(self.ENTRYSTRUCT + repr(nmlen) + 's',nmlen + entrylen, dpos, dlen, ulen, flag, typcd, str(nm + pad)))