Python: excluding Pyinstaller modules

I started using Pyinstaller over Py2Exe. However, I ran into a problem pretty quickly. How can I exclude modules that I do not need, and how to view those that are in the same executable?

I can delete some pyd and dll files from the DLL folder in my Python installation, so Pyinstaller will not find and therefore will not enable them. I really do not want to do this with all modules, as it will be quite difficult.

I tried to edit the specification file that Pyinstaller does.

 a.binaries - [('ssl','pydoc',)], 

But the file size remained the same, so I came to the conclusion that this did not work.

So, how can I see which modules contain Pyinstaller, and how can I exclude the ones I don't need?

+10
source share
4 answers

Just to summarize the options here when I use them.

PyInstaller TOC - there is, as the documentation says:

A TOC is a list of tuples of a form (name, path, TypeCode). This is actually an ordered set, not a list. TOC does not contain duplicates where uniqueness is based only on a name.

In other words, simply:

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

So, in your .spec file - after you get the results of the analysis of the script, you can additionally change the corresponding TOC:

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

  • To add / remove lists of files / modules of iteration by TOC and comparison with the template matching code.

(* Aside, for the difference in work, it seems you should use TOC() explicitly and note that, since this is only a name that uniquely identifies a collection element, you only need to indicate that - therefore ('sqlite3', None, None) etc.)

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

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

 # 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")] 
+23
source

You can manipulate the lists created by the Analysis class using Python. Please note that they are in TI PyInstaller format.

 a = Analysis(...) ... # exclude anything from the Windows system dir a.binaries = [x for x in a.binaries if not os.path.dirname(x[1]).startswith("C:\\Windows\\system32")] 
+4
source

Although better solutions may be given, there is another method: you can use the --exclude-module attribute with the pyinstaller command, but this method is long enough when you need to exclude many modules.

To simplify the work, you can write a batch script file with all the libraries that are worth skipping and use it again and again.

More or less like this:

 @echo off pyinstaller --onefile a.py --exclude-module matplotlib ^ --exclude-module scipy ^ --exclude-module setuptools ^ --exclude-module hook ^ --exclude-module distutils ^ --exclude-module site ^ --exclude-module hooks ^ --exclude-module tornado ^ --exclude-module PIL ^ --exclude-module PyQt4 ^ --exclude-module PyQt5 ^ --exclude-module pydoc ^ --exclude-module pythoncom ^ --exclude-module pytz ^ --exclude-module pywintypes ^ --exclude-module sqlite3 ^ --exclude-module pyz ^ --exclude-module pandas ^ --exclude-module sklearn ^ --exclude-module scapy ^ --exclude-module scrapy ^ --exclude-module sympy ^ --exclude-module kivy ^ --exclude-module pyramid ^ --exclude-module opencv ^ --exclude-module tensorflow ^ --exclude-module pipenv ^ --exclude-module pattern ^ --exclude-module mechanize ^ --exclude-module beautifulsoup4 ^ --exclude-module requests ^ --exclude-module wxPython ^ --exclude-module pygi ^ --exclude-module pillow ^ --exclude-module pygame ^ --exclude-module pyglet ^ --exclude-module flask ^ --exclude-module django ^ --exclude-module pylint ^ --exclude-module pytube ^ --exclude-module odfpy ^ --exclude-module mccabe ^ --exclude-module pilkit ^ --exclude-module six ^ --exclude-module wrapt ^ --exclude-module astroid ^ --exclude-module isort 

Or you can always use a new Python installation, just change the path of the new Python installation during installation.

+1
source

FIND ANSWER YOURSELF

I have seen many similar questions, but no one is teaching you how to debug yourself.

The Pyinstaller document may be useful for beginners, but as soon as you need more ...

I personally think that the pyinstaller documentation is not friendly (too few examples) and has no updates.

For example, the document shows pyinstaller version 3.2. (3.5 available now (2019/10/5))

I want to say that you should find the answer from the source code

START WAY

  • create a script file (e.g. run_pyinstaller.py) as shown below:
 # run_pyinstaller.py from PyInstaller.__main__ import run run() 
  • Before running this script, you can assign parameters, for example, " --clean your.spec "

  • set a breakpoint on {env_path}/Lib/site-packages/PyInstaller/building/build_main.py -> def build(...) ... -> exec(code, spec_namespace) , as shown below:

    note: if you are not using a virtual environment, the actual path should be {Python} /Lib/site-packages/PyInstaller/building/build_main.py

enter image description here

  • finally, you run here and press the go to button. You will be taken to the .spec file

then you can look at any variables that interest you.

In addition, you will learn more about pyinstaller.exe actually doing.

for example, you learn that the table of contents class is inherited from the list, and you see more details than the document from PyInstaller.building.datastruct

enter image description here

after all, you can use any Python method to install a.binaries and a.datas that you really wanted

UNITED FILES

 from PyInstaller.building.datastruct import TOC, Tree from PyInstaller.building.build_main import Analysis from PyInstaller.building.api import EXE, PYZ, COLLECT, PKG, MERGE 
0
source

All Articles