Error freezing h5py 2.4 with cx_freeze 4.3.1

I am trying to freeze a Python script using cx_Freeze. The script uses h5py v2.4.0b1. When I run the executable file created by cx_Freeze I get the following Traceback:

Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>
    exec(code, m.__dict__)
  File "main.py", line 7, in <module>
    from xman import xmanLogging, xmanManager, xmanInfo
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
  File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\__init__.py", line 3, in <
module>
    from .xmlHandler import barMAN, xmlClass
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
  File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\xmlHandler\__init__.py", l
ine 7, in <module>
    from . import barMAN, xmlClass
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2284, in _handle_fromlist
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 321, in _call_with_frames_removed
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
  File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\xmlHandler\xmlClass.py", l
ine 25, in <module>
    from xman.COMInterface import COMmanager
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
  File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\COMInterface\__init__.py",
 line 7, in <module>
    from . import COMmanager
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2284, in _handle_fromlist
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 321, in _call_with_frames_removed
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
  File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\COMInterface\COMmanager.py
", line 20, in <module>
    import logging, win32com.client , pythoncom, pywintypes, h5py, \
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
  File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
  File "C:\Python34\lib\site-packages\h5py\__init__.py", line 10, in <module>
    from h5py import _errors
ImportError: cannot import name '_errors'

      

I am using Python 3.4.2 - 32 bit. Anyone have an idea?

+3


source to share


1 answer


I spent two days trying to figure this out.

I am using python 2.7 64-bit but I got the same error as windows, ubuntu 14 and mac os 10.9 and 10.10. I am also using h5py 2.4.0 and cx_Freeze 4.3.4.

The solution for me was as follows:

https://bitbucket.org/anthony_tuininga/cx_freeze/pull-request/64/only-add-h5pyapi_gen-if-it-can-be-imported/diff

I had to change the hooks.py in cx_Freeze for load_h5py so that:

def load_h5py(finder, module):
   """h5py module has a number of implicit imports"""
   finder.IncludeModule('h5py.defs')
   finder.IncludeModule('h5py.utils')
   finder.IncludeModule('h5py._proxy')
   try:
      finder.IncludeModule('h5py._errors')
      finder.IncludeModule('h5py.h5ac')
   except:
      pass
   try:
      finder.IncludeModule('h5py.api_gen')
   except:
      pass

      



Also, it seems that some of the h5py. *, so links to links with

@ loader_path / .dylibs / libhdf5.8.dylib

This is not overwritten by cx_freeze.

I had to change the code in cx_freeze (actually, I copied the code into my setup.py and just called it right after calling the main setup (....) to send all files in the assembly)

    # this is a straight copy paste from macdist.py in the cx_Freeze code
def setRelativeReferencePaths(binDir):
    """ For all files in Contents/MacOS, check if they are binaries
        with references to other files in that dir. If so, make those
        references relative. The appropriate commands are applied to all
        files; they will just fail for files on which they do not apply."""
    files = []
    for root, dirs, dir_files in os.walk(binDir):
        files.extend([os.path.join(root, f).replace(binDir + "/", "")
                      for f in dir_files])
    for fileName in files:

        # install_name_tool can't handle zip files or directories
        filePath = os.path.join(binDir, fileName)
        if fileName.endswith('.zip'):
            continue

        # ensure write permissions
        mode = os.stat(filePath).st_mode
        if not (mode & stat.S_IWUSR):
            os.chmod(filePath, mode | stat.S_IWUSR)

        # let the file itself know its place
        subprocess.call(('install_name_tool', '-id',
                         '@executable_path/' + fileName, filePath))

        # find the references: call otool -L on the file
        otool = subprocess.Popen(('otool', '-L', filePath),
                                 stdout=subprocess.PIPE)
        references = otool.stdout.readlines()[1:]

        for reference in references:

            # find the actual referenced file name
            referencedFile = reference.decode().strip().split()[0]

            if referencedFile.startswith('@loader_path/.dylibs/'):
                # this file is likely an hdf5 file
                print "Found hdf5 file {} referencing {}".format(filePath, referencedFile)
            elif referencedFile.startswith('@'):
                # the referencedFile is already a relative path
                continue

            path, name = os.path.split(referencedFile)

            # some referenced files have not previously been copied to the
            # executable directory - the assumption is that you don't need
            # to copy anything fro /usr or /System, just from folders like
            # /opt this fix should probably be elsewhere though
            # if (name not in files and not path.startswith('/usr') and not
            #        path.startswith('/System')):
            #    print(referencedFile)
            #    self.copy_file(referencedFile,
            #                   os.path.join(self.binDir, name))
            #    files.append(name)

            # see if we provide the referenced file;
            # if so, change the reference
            if name in files:
                newReference = '@executable_path/' + name
                subprocess.call(('install_name_tool', '-change',
                                 referencedFile, newReference, filePath))

      

+4


source







All Articles