6

I have a Python app based on Twisted and PyGTK. Twisted itself depends on zope.interface, and I don't import it directly.

Unfortunately, when I try to run my app, the following error ends up in the error log:

Traceback (most recent call last):
  File "tasks.py", line 4, in <module>
  File "ui\__init__.pyc", line 14, in <module>
  File "twisted\python\log.pyc", line 17, in <module>
ImportError: No module named zope.interface
Traceback (most recent call last):
  File "tasks.py", line 4, in <module>
  File "ui\__init__.pyc", line 14, in <module>
  File "twisted\python\log.pyc", line 17, in <module>
ImportError: No module named zope.interface
Traceback (most recent call last):
  File "tasks.py", line 4, in <module>
  File "ui\__init__.pyc", line 14, in <module>
  File "twisted\python\log.pyc", line 17, in <module>
ImportError: No module named zope.interface

I've tried adding every combination of zope.interface and zope to INCLUDES and PACKAGES, but doing so only gives me this build time error:

running py2exe
*** searching for required modules ***
C:\Python26\lib\site-packages\py2exe\build_exe.py:16: DeprecationWarning: the sets module is deprecated
  import sets
Traceback (most recent call last):
  File "setup.py", line 75, in <module>
    'gtk/*.ui'
  File "C:\Python26\lib\distutils\core.py", line 152, in setup
    dist.run_commands()
  File "C:\Python26\lib\distutils\dist.py", line 975, in run_commands
    self.run_command(cmd)
  File "C:\Python26\lib\distutils\dist.py", line 995, in run_command
    cmd_obj.run()
  File "C:\Python26\lib\site-packages\py2exe\build_exe.py", line 243, in run
    self._run()
  File "C:\Python26\lib\site-packages\py2exe\build_exe.py", line 296, in _run
    self.find_needed_modules(mf, required_files, required_modules)
  File "C:\Python26\lib\site-packages\py2exe\build_exe.py", line 1306, in find_needed_modules
    mf.import_hook(f)
  File "C:\Python26\lib\site-packages\py2exe\mf.py", line 719, in import_hook
    return Base.import_hook(self,name,caller,fromlist,level)
  File "C:\Python26\lib\site-packages\py2exe\mf.py", line 136, in import_hook
    q, tail = self.find_head_package(parent, name)
  File "C:\Python26\lib\site-packages\py2exe\mf.py", line 204, in find_head_package
    raise ImportError, "No module named " + qname
ImportError: No module named zope

My setup.py is:

from distutils.core import setup
import py2exe

def find_data_files(source,target,patterns):
    # I've elided this, I doubt it's relevant to the problem
    # ...

INCLUDES = [
    'cairo',
    'pango',
    'pangocairo',
    'atk',
    'gobject',
    'gio',
]

PACKAGES = [
    'encodings',
]

setup(
    name = 'MyApp',
    description = 'My Application',
    version = '1.0',

    windows = [
                  {
                      'script': os.path.join('ui','tasks.py'),
                      'icon_resources': [
                            (1, os.path.join(
                                'ui','data','iconpack.ico'))
                        ],
                  }
              ],

    options = {
                  'py2exe': {
                      'packages': ','.join(PACKAGES),
                      'includes': ','.join(INCLUDES),
                  }
              },

    data_files = find_data_files(
                    'ui', 'ui', [
                        'data/*',
                        'gtk/*.ui'
                    ])

)

How do I get py2exe to build this?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
detly
  • 29,332
  • 18
  • 93
  • 152

3 Answers3

24

I don't know if you ever solved this, or if it's even relevant to you anymore, but for future searchers, I found an easy way to fix the zope import problem here.

Specifically, add an empty __init__.py file to the PYTHONDIR/Lib/site-packages/zope directory.

I tested this with a twisted application, using this setup file:

#!/usr/bin/env python
'''
File: setup.py
Author: Spencer Rathbun
Date: 07/24/2012
Description: Setup file for py2exe, converts client python script into executable.
'''
from distutils.core import setup
import py2exe

INCLUDES = [
    ''
]

PACKAGES = [
    'twisted'
]

setup(
        name = 'client',
        description = '',
        version = '1.0',

        console = [
            {"script":"client.py",
                "icon_resources":[
                    (1, "c:\python27\DLLs\py.ico")
                    ]
                }
            ],
        zipfile = None,

        options = {"py2exe":
            {"compressed": 1,
                "optimize": 1,
                "ascii": 0,
                "bundle_files": 1,

                "packages": ','.join(PACKAGES),
                "includes": ','.join(INCLUDES),
                }
            }
        )

Py2exe can use this to successfully create an executable for twisted now, since it depends upon zope.

Spencer Rathbun
  • 14,510
  • 6
  • 54
  • 73
5

I've had this same problem with zope.interface and friends (zope.component, et al). Specifically it is a problem with how py2exe searches and discovers packages AND how the zope packages are installed.

zope is a namespace package and as a result relies on some funky import logic in it's .pth files (see zope.interface-3.*.*-py2.*-nspkg.pth) in order to add it's sub-packages to python's path. Have a look at it in site-packages and you'll see what I mean.

py2exe has problems "discovering" this kind of package.

In the end what I did was manually repackage the various zope packages I was using into a stardard module setup in site-packages and then reran py2exe - which then discovered everything no problem. It's a PITA, but until py2exe is able to handle packaging edge cases and/or the zope packages are packaged in a py2exe friendly fashion, it's about the best you can do.

Mark Gemmill
  • 5,889
  • 2
  • 27
  • 22
  • I went to check that I could do this without running afoul of their license. Is it just me, or is the Zope Public License not actually included with any of their distributions? – detly Oct 19 '11 at 06:59
  • There is a reference to the license include at the top of the actual code files - which is all they need. You are not doing anything contrary to the license (i.e. you are not actually changing the code in any way), you're just altering how the package is installed on your system. It's not any different than what py2exe already does with all your python libraries it packs into an exe. – Mark Gemmill Oct 19 '11 at 07:14
  • Bah, [here it is](http://bazaar.launchpad.net/~ztk-steering-group/zope.interface/trunk/view/head:/LICENSE.txt). – detly Oct 19 '11 at 07:16
  • my impression is that it'd still be creating a derived work, but it looks like the license is fairly liberal about that anyway, so no matter. – detly Oct 19 '11 at 07:20
  • Okay, I'm marking this as the answer, since it got me past this phase, but now py2exe is choking on pretty much every other package I use so I'm abandoning it. So for anyone else reading this, I have no way to verify whether it worked in the final built executable :/ – detly Oct 20 '11 at 01:56
  • ah, yeah, py2exe takes a bit of work sometimes to get all the various packages to bundle. Usually py2exe is pretty good at letting you know which libraries it has trouble with, but some (like zope) take some investigation. There are a number of tips, etc. on the py2exe website, but its a bit disorganized and takes a bit of digging. I've packaged an app with wxPython, zope, and a few others and it took me several painful days to sort through the problem. Once it was done, everything worked nicely. Getting there is just a PITA. – Mark Gemmill Oct 20 '11 at 04:44
  • Yeah, maybe I just need to stick with it. I get the feeling it's not going to be easier with any other system. – detly Oct 20 '11 at 04:59
  • Having to repackage can be avoided by using Spencer's really simple answer below. – Adam Nemitoff Feb 05 '14 at 17:24
3

I was facing this issue in creating a package using py2exe in Windows XP SP3. I figured out that py2exe was not determining the dependencies correctly.

To solve this issue, I uninstalled my third party package(s) and installed them using following easy_install command

easy_install -Z <your_package_name>

The -Z option unzips the package details, and hence the content is not compressed. When you run py2exe now, it will correctly detect the dependencies.

Hope this helps!

AUR
  • 623
  • 7
  • 14