Freezing a very simple script fails with PyTables 3.3.0 and PyInstaller 3.3.1 on Windows 10.
To create a test environment using the EDM tool:
C:\Enthought\frozen-tables>edm install pytables pywin32 -e frozen_tables
C:\Enthought\frozen-tables>edm run -e frozen_tables -- pip install pyinstaller
Some debugging info:
C:\Enthought\frozen-tables>edm run -e frozen_tables -- python --version
Python 2.7.13 -- Enthought, Inc. (x86_64)
C:\Enthought\frozen-tables>edm run -e frozen_tables -- pip list
altgraph (0.15)
appdirs (1.4.3)
dis3 (0.1.2)
distribute-remove (1.0.0)
future (0.16.0)
macholib (1.9)
MKL (2017.0.3)
numexpr (2.6.2)
numpy (1.13.3)
packaging (16.8)
pefile (2017.11.5)
pip (9.0.1)s
PyInstaller (3.3.1)
pyparsing (2.2.0)
pytables (3.3.0)
pywin32 (220)
setuptools (38.2.5)
six (1.10.0)
Create a freeze.py
script which imports PyTables and calls the print_versions
function. It's output:
C:\Enthought\frozen-tables>edm run -e frozen_tables -- python freeze.py
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
PyTables version: 3.3.0
HDF5 version: 1.8.16
NumPy version: 1.13.3
Numexpr version: 2.6.2 (using VML/MKL 2017.0.3)
Zlib version: 1.2.8 (in Python interpreter)
Blosc version: 1.11.1 (2016-09-03)
Blosc compressors: blosclz (1.0.5), lz4 (1.7.2), lz4hc (1.7.2), snappy (1.1.1), zlib (1.2.8), zstd (1.0.0)
Blosc filters: shuffle, bitshuffle
Python version: 2.7.13 |Enthought, Inc. (x86_64)| (default, Mar 2 2017, 16:05:12) [MSC v.1500 64 bit (AMD64)]
Platform: Windows-10-10.0.16299
Byte-ordering: little
Detected cores: 4
Default encoding: ascii
Default FS encoding: mbcs
Default locale: (en_US, cp1252)
Then freeze the script with --onedir
or --onefile
. Both versions fail, each for a slightly different reason.
The --onefile
version fails for reasons which I have not been able to figure out. Ostensibly, it's failing to load the hdf5.dll
library. The file is present, and if I insert a breakpoint into the PyInstaller ctypes.cdll
machinery, I see that the actual error from LoadLibrary
is: WindowsError: [Error 126] The specified module could not be found
. I find that error confusing, to say the least. Calling os.path.exists
on the same path returns True
. While the script is blocked in the Python debugger, I made a copy of the hdf5.dll
library within and I see nothing wrong when I examine it using Dependency Walker.
The --onedir
version fails because the PyInstaller ctypes.cdll
machinery raises an exception when a library is not found, rather than returning None
as is expected by code running against an unpatched ctypes
. Namely, the checks for lzo2.dll and libbz2.dll will fail because the files are not present (causing an exception in the frozen script). Examining the affected code: https://github.com/PyTables/PyTables/blob/develop/tables/__init__.py#L76-L86 we see that PyTables is OK with getting a None
back from LoadLibrary
, so the files don't actually have to be present.
The problem can be resolved by skipping the LoadLibrary
sanity check in PyTables, as suggested in PyTables/PyTables#177.