Python: Excluding Modules Pyinstaller

Just to summarise the options here as I use them.

PyInstaller TOC’s – are, as the documentation says:

A TOC appears to be a list of tuples of the form (name, path,
typecode). In fact, it’s an ordered set, not a list. A TOC contains no
duplicates, where uniqueness is based on name only.

In otherwords, simply:

a_toc = [('uname1','/path/info','BINARY'),('uname2','/path/to','EXTENSION')...]

So, in your .spec file – once you’ve got the Analysis results of the script – you can then further modify the respective TOC’s by either:

  • For specific files/modules use the difference (-) and intersection (+) operations to modify a TOC. *

  • For adding/removing lists of files/modules iterate over the the TOC and compare with pattern matching code.

(* As an aside, for the difference to work it seems you must explicitly cast to TOC() and note that since it is only the name that uniquely defines the element of the set, you only need to specify that – hence ('sqlite3', None, None) etc.)

An illustrative example (taken from a .spec file) is below where – for better or worse – I remove all references to scipy, IPython and zmq; delete specific sqlite, tcl/tk and ssl .DLL’s; insert a missing opencv .DLL; and finally remove all data folders found apart from matplotlib ones…

Whether the resulting Pyinstaller .exe will then work when an .pyc file tries to load an expected .DLL is moot:-/

# Manually remove entire packages...

a.binaries = [x for x in a.binaries if not x[0].startswith("scipy")]

a.binaries = [x for x in a.binaries if not x[0].startswith("IPython")]

a.binaries = [x for x in a.binaries if not x[0].startswith("zmq")]

# Target remove specific ones...

a.binaries = a.binaries - TOC([
 ('sqlite3.dll', None, None),
 ('tcl85.dll', None, None),
 ('tk85.dll', None, None),
 ('_sqlite3', None, None),
 ('_ssl', None, None),
 ('_tkinter', None, None)])

# Add a single missing dll...

a.binaries = a.binaries + [
  ('opencv_ffmpeg245_64.dll', 'C:\\Python27\\opencv_ffmpeg245_64.dll', 'BINARY')]

# Delete everything bar matplotlib data...

a.datas = [x for x in a.datas if
 os.path.dirname(x[1]).startswith("C:\\Python27\\Lib\\site-packages\\matplotlib")]

Leave a Comment