1

I have a wxpython program where I keep the picture files in a zip file. Program runs fine while running by python. But when I run pyinstaller to produce exe file, I get IO error. Here is my program.

import zipfile
import wx
from PIL import Image
from StringIO import StringIO

def PilImageToWxImage(myPilImage):
    myWxImage = wx.EmptyImage(myPilImage.size[0], myPilImage.size[1])
    myWxImage.SetData(myPilImage.convert('RGB').tostring())
    return myWxImage

class Frame1(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        z = zipfile.ZipFile("Data.zip", "r")
        zl = z.namelist()
        x = z.read(zl[0])
        y = StringIO(x)
        w = Image.open(y)
        v = PilImageToWxImage(w).ConvertToBitmap()
        u = wx.EmptyIcon()
        u.CopyFromBitmap(v)
        self.SetIcon(u)

if __name__ == "__main__":
    a = wx.App(0)
    f = Frame1(None, -1, "Test")
    f.Show()
    a.MainLoop()

This program runs ok when I run by python test.py from command prompt. But when I run the test.exe file produced by pyinstaller --onefile --console --upx-dir='J:\Programs' test.py, I get error :

Traceback (most recent call last):
File "<string>", line 26, in <module>
File "<string>", line 18, in __init__
File "J:\Programs\Python\PyInstaller\build\test\out00-PYZ.pyz\PIL.Image", line 2274, in open
IOError: cannot identify image file <StringIO.StringIO instance at 0x00000000048E1BC8>

I cannot figure what is wrong here. Please help.

Thanks.

Joydeep
  • 147
  • 14
  • possible duplicate of [Bundling data files with PyInstaller (--onefile)](http://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile) – nepix32 Apr 30 '15 at 13:57
  • I also flagged the question so you have the link to an answer (which is quite complicated for ``--onefile``) on SO. – nepix32 Apr 30 '15 at 13:58

1 Answers1

0

Unless you did not edit the .spec file/wrote a hook file your ZIP file does not get included during packing automagically.

See where the onefile stores the temporary files. If possible, you can look during runtime if the ZIP file is in the supposed place.

Otherwise you have to build without --onefile and check, if the ZIP is there. You can check if the error goes away if you copy the ZIP to the dir where the .EXE is (will of course only work if you have not used --onefile).

Search the PyInstaller doc page for data files and choose the method best suited for your purpose.

nepix32
  • 3,012
  • 2
  • 14
  • 29
  • Could you please elaborate what I need to add in my spec file? What should I write in the spec file to add a hook for zip file? My zipfile is in the same folder `os.getcwd()` as my py file. Thanks – Joydeep Apr 30 '15 at 15:33
  • Have you tried the accepted answer in the linked post, see my comment below your question? (No spoonfeeding) – nepix32 Apr 30 '15 at 16:22
  • I forgot to mention, I had already resource_path function in my program and configured my spec file as mentioned in [http://irwinkwan.com/2013/04/29/python-executables-pyinstaller-and-a-48-hour-game-design-compo/]. But I was getting the same error. Then I changed the function as in accepted answer suggested by you. Now I am getting a different error: `File "J:\Programs\Python\PyInstaller\build\test\out00-PYZ.pyz\zipfile", line 756, in __init__ IOError: [Errno 2] No such file or directory: 'C:\\Users\\Joydeep\\AppData\\Local\\Temp\\_MEI23442\\Data.zip'` – Joydeep May 01 '15 at 07:46
  • I got the same problem. Figured out that I had to give PyInstaller the spec file, **not** the py file (otherwise PyInstaller will happily create the spec file again and losing all your effort). – nepix32 May 01 '15 at 17:48
  • I put the resource_path function in the spec file, but getting the same error as above comment. I tried with `path = getattr(sys, '_MEIPASS', os.getcwd())` in spec file also, but got the same error. However, if I extract the zip file to another folder, then the program runs fine. But I don't like that solution. – Joydeep May 02 '15 at 15:42
  • Why on all earth would you put the ``resource_path`` function in the spec file!?! Have you tried to understand what and why things go to which file? You have still not answered (yourself) the following questions: Why do I need ``resource_path`` (HINT: to find the ZIP at runtime in ``_MEI``)? How do I make PyInstaller include the ZIP file? (Hint: by adding ``a.datas += [('Data.zip', 'Data.zip', 'DATA')]`` directly after the ``a = ...`` statement in the spec file). – nepix32 May 02 '15 at 16:37
  • Yes, it worked. Thank you very much for the hints (and scolding!) +1 – Joydeep May 04 '15 at 11:42