Repository: pyinstaller/pyinstaller

Issue:
unable to freeze python application with pyinstaller
When freezing my tkinter application..
this happened
```
Building directory: C:\Users\Lenovo\AppData\Local\Temp\tmpf5g2f1iq
Provided command: pyinstaller --noconfirm --onefile --windowed --icon "E:/Programming/WhirlEdit/favicon.v3.ico" --name "WhirlEdit" --version-file "E:/Programming/WhirlEdit/WhirlEdit_2.txt"  "E:/Programming/WhirlEdit/alpha.py"
Recursion Limit is set to 5000
Executing: pyinstaller --noconfirm --onefile --windowed --icon E:/Programming/WhirlEdit/favicon.v3.ico --name WhirlEdit --version-file E:/Programming/WhirlEdit/WhirlEdit_2.txt E:/Programming/WhirlEdit/alpha.py --distpath C:\Users\Lenovo\AppData\Local\Temp\tmpf5g2f1iq\application --workpath C:\Users\Lenovo\AppData\Local\Temp\tmpf5g2f1iq\build --specpath C:\Users\Lenovo\AppData\Local\Temp\tmpf5g2f1iq

67192 INFO: PyInstaller: 4.3
67200 INFO: Python: 3.8.10
67248 INFO: Platform: Windows-7-6.1.7601-SP1
67255 INFO: wrote C:\Users\Lenovo\AppData\Local\Temp\tmpf5g2f1iq\WhirlEdit.spec
67269 INFO: UPX is not available.
67282 INFO: Extending PYTHONPATH with paths
['E:\\Programming\\WhirlEdit',
 'C:\\Users\\Lenovo\\AppData\\Local\\Temp\\tmpf5g2f1iq']
An error occurred while packaging
Traceback (most recent call last):
  File "e:\programming\python38-32\lib\site-packages\auto_py_to_exe\packaging.py", line 131, in package
    run_pyinstaller()
  File "e:\programming\python38-32\lib\site-packages\PyInstaller\__main__.py", line 114, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "e:\programming\python38-32\lib\site-packages\PyInstaller\__main__.py", line 65, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "e:\programming\python38-32\lib\site-packages\PyInstaller\building\build_main.py", line 737, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "e:\programming\python38-32\lib\site-packages\PyInstaller\building\build_main.py", line 684, in build
    exec(code, spec_namespace)
  File "C:\Users\Lenovo\AppData\Local\Temp\tmpf5g2f1iq\WhirlEdit.spec", line 7, in <module>
    a = Analysis(['E:/Programming/WhirlEdit/alpha.py'],
  File "e:\programming\python38-32\lib\site-packages\PyInstaller\building\build_main.py", line 212, in __init__
    self.hookspath += list(entry_point.load()())
  File "e:\programming\python38-32\lib\site-packages\pkg_resources\__init__.py", line 2449, in load
    self.require(*args, **kwargs)
  File "e:\programming\python38-32\lib\site-packages\pkg_resources\__init__.py", line 2472, in require
    items = working_set.resolve(reqs, env, installer, extras=self.extras)
  File "e:\programming\python38-32\lib\site-packages\pkg_resources\__init__.py", line 772, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'kivy>=2.0.0' distribution was not found and is required by the application

Project output will not be moved to output folder
Complete.
```
later on, i made another file... with no imports at all..
and still, the same error occured!


Discussion:
> later on, i made another file... with no imports at all..
and still, the same error occured!

The error is triggered when PyInstaller tries to enumerate 3rd-party hooks from installed packages in the environment, and it is going to occur any time you run PyInstaller regardless of what imports your script uses.

That said, do you have `kivy` installed in your environment? Can we see output of `pip freeze`?

> That said, do you have `kivy` installed in your environment? 
no, but when i have kivy, then the program.. that i expect to be 20mb in size became 132mb in size..

and `pip freeze`'s output:
```
a8==1.0
alabaster==0.7.12
altgraph==0.17
anyio==3.1.0
AnyQt==0.0.13
appdirs==1.4.4
argon2-cffi==20.1.0
arrow==1.1.0
art==5.2
asciimatics==1.13.0
astroid==2.5.6
asttokens==2.0.5
async-generator==1.10
atomicwrites==1.4.0
attrs==21.2.0
auto-py-to-exe==2.9.0
autopep8==1.5.5
b8==0.2.3
Babel==2.9.1
backcall==0.2.0
bcrypt==3.2.0
binaryornot==0.4.4
black==21.5b1
bleach==3.3.0
blessings==1.7
bottle==0.12.19
bottle-websocket==0.2.9
bpython==0.21
braces.py==0.4.0
browser==0.0.1
brython==3.9.4
cachetools==4.2.2
cefpython3==66.1
certifi==2020.12.5
cffi==1.14.5
chardet==4.0.0
check-availability==0.1.1
check-pypi-name==0.4.0
cheroot==8.5.2
CherryPy==18.6.0
click==8.0.1
cloudpickle==1.6.0
colorama==0.4.4
coloredlogs==15.0
colosseum==0.2.0
compie @ file:///E:/Sapphire/Programming/Python%20Modules/compie
confapp==1.1.11
construct==2.0.6
cookiecutter==1.7.3
cryptography==3.4.7
cssselect==1.0.3
curtsies==0.3.5
cwcwidth==0.1.4
cx-Freeze==6.6
cx-Logging==3.0
cycler==0.10.0
Cython==0.29.23
decorator==4.4.2
defusedxml==0.7.1
Deprecated==1.2.12
dialite==0.5.3
diff-match-patch==20200713
distlib==0.3.1
docopt==0.6.2
docutils==0.16
EasyProcess==0.3
EditorConfig==0.12.3
Eel==0.12.4
enolib==0.8.1
entrypoint2==0.2.4
entrypoints==0.3
ffmpeg-python==0.2.0
ffmpy==0.3.0
filelock==3.0.12
flake8==3.9.2
flexx==0.8.1
future==0.18.2
gevent==21.1.2
gevent-websocket==0.10.1
gitdb==4.0.7
GitPython==3.1.18
glfw==2.1.0
greenlet==1.1.0
grequests==0.6.0
helpdev==0.7.1
humanfriendly==9.1
idna==2.10
imagesize==1.2.0
importlib-metadata==4.0.1
inflection==0.5.1
iniconfig==1.1.1
intervaltree==3.1.0
ipykernel==5.5.5
ipython==7.25.0
ipython-genutils==0.2.0
isort==5.8.0
jaraco.classes==3.2.1
jaraco.collections==3.3.0
jaraco.functools==3.3.0
jaraco.text==3.5.0
jedi==0.17.2
Jinja2==3.0.1
jinja2-time==0.2.0
json5==0.9.5
jsonschema==3.2.0
jupyter-client==6.1.12
jupyter-core==4.7.1
jupyter-offlinenotebook==0.2.1
jupyter-server==1.8.0
jupyterlab==3.0.16
jupyterlab-pygments==0.1.2
jupyterlab-server==2.6.0
kaadbg==0.3.0
kaki==0.1.4
keyring==23.0.1
kivy-deps.angle==0.3.0
kivy-deps.glew==0.3.0
kivy-deps.sdl2==0.3.1
Kivy-Garden==0.1.4
kivymd @ https://github.com/kivymd/KivyMD/archive/master.zip
kivymd-extensions.sweetalert==0.1.5
kiwisolver==1.3.1
kurt==2.0.7
lazy-object-proxy==1.6.0
Logbook==1.5.3
logilab-common==1.8.1
lxml==4.5.0
Mako==1.1.4
Markdown==3.3.4
markdown2==2.4.0
MarkupSafe==2.0.1
matplotlib==3.4.2
matplotlib-inline==0.1.2
mccabe==0.6.1
mercurial==5.8
mistune==0.8.4
monotonic==1.6
more-itertools==8.8.0
mp3play==0.1.15
msgpack==1.0.2
mss==6.1.0
mutagen==1.45.1
mypy==0.910
mypy-extensions==0.4.3
natsort==7.1.1
nbclassic==0.2.8
nbclient==0.5.3
nbconvert==6.0.7
nbformat==5.1.3
nest-asyncio==1.5.1
nodebox-opengl @ file:///C:/Users/Lenovo/Downloads/nodebox-gl-1.7
notebook==6.4.0
npyscreen==4.10.5
nuitka==0.6.17rc2
Nuitka32==6.1.151
numpy==1.20.3
numpydoc==1.1.0
opencv-python==4.5.2.52
packaging==20.9
pandocfilters==1.4.3
paramiko==2.7.2
parso==0.7.1
pastel==0.2.1
pathspec==0.8.1
pdfminer==20191125
pefile==2021.5.24
pep517==0.6.0
pexpect==4.8.0
pickleshare==0.7.5
picotui==1.2
Pillow==8.2.0
pipe==1.6.0
pival==1.1.1
pkginfo==1.7.0
pluggy==0.13.1
ply==3.11
plyer==2.0.0
portend==2.7.1
poyo==0.5.0
Proget==1.0.1
prometheus-client==0.10.1
prompt-toolkit==3.0.18
pscript==0.7.5
psutil==5.8.0
ptpython==3.0.19
ptyprocess==0.7.0
py==1.10.0
py-cpuinfo==8.0.0
py-cui==0.1.3
pyautogit==0.0.5
pycodestyle==2.7.0
pycparser==2.20
pycryptodome==3.10.1
pydocstyle==6.1.1
pyee==8.1.0
pyenchant==3.2.1
pyfiglet==0.8.post1
pyflakes==2.3.1
PyForms-GUI==5
pygame==2.0.1
PyGithub==1.55
pyglet==1.5.18
PyGLM==2.2.0
Pygments==2.9.0
pygtkhelpers==0.4.3
pygubu==0.11
pygubu-designer==0.17
pyinstaller==4.4
pyinstaller-hooks-contrib==2021.2
pyinstaller-versionfile==2.0.0
pyjf3==0.3
PyJWT==2.1.0
pylexer==1.0.0
pylint==2.8.3
pyls-black==0.4.6
pyls-spyder==0.3.2
PyNaCl==1.4.0
pynsist==2.7
PyOpenGL @ file:///C:/Users/Lenovo/Downloads/PyOpenGL-3.1.5-cp38-cp38-win32.whl
PyOpenGL-accelerate @ file:///C:/Users/Lenovo/Downloads/PyOpenGL_accelerate-3.1.5-cp38-cp38-win32.whl
pyOpenSSL==20.0.1
pyoxidizer==0.16.2
pypager==3.0.0
pyparsing==2.4.7
pypi-name==1.0.0
pypiwin32==223
PyQt5==5.15.4
PyQt5-Qt5==5.15.2
PyQt5-sip @ file:///C:/Users/Lenovo/Downloads/pyqt5_sip-12.8.1-cp38-cp38-win32.whl
PyQtChart==5.15.4
PyQtChart-Qt5==5.15.2
pyqtdeploy==3.1.1
PyQtWebEngine==5.15.4
PyQtWebEngine-Qt5==5.15.2
pyreadline==2.1
pyrsistent==0.17.3
pyscreenshot==3.0
PySDL2==0.9.7
pysdl2-dll==2.0.14.post2
pyserial==3.5
pyte==0.5.2
pytermgui==0.0.7
pytest==6.2.4
python-dateutil==2.8.1
python-ffmpeg==1.0.11
python-for-android==2020.6.2
python-jsonrpc-server==0.4.0
python-language-server==0.36.2
python-slugify==5.0.2
python-vlc==3.0.12118
pythonnet==2.5.2
pytoml==0.1.21
pytov==0.2.7
pytz==2021.1
pyunity @ https://ci.appveyor.com/api/buildjobs/nresgpnbasjcw8si/artifacts/dist/pyunity-0.7.0-cp38-cp38-win32.whl
pyunity-editor @ file:///E:/Programming/pyunity-gui
pyvim==3.0.2
PyVirtualDisplay==0.2.4
pywin32==301
pywin32-ctypes==0.2.0
pywinpty==0.5.7
pyxdg==0.27
PyYAML==5.4.1
pyzmq==22.0.3
QDarkStyle==3.0.2
QScintilla==2.13.0
qstylizer==0.2.0
QtAwesome==1.0.2
qtconsole==5.1.0
QtPy==1.9.0
ranger-fm==1.9.3
readme-renderer==29.0
regex==2021.4.4
requests==2.25.1
requests-download==0.1.2
requests-toolbelt==0.9.1
rfc3986==1.5.0
rope==0.19.0
Rtree @ file:///C:/Users/Lenovo/Downloads/rtree-0.9.7.tar.gz
s-tui==1.1.1
selenium==3.141.0
Send2Trash==1.5.0
setproctitle==1.2.2
sh==1.14.2
sip==6.0.3
six==1.16.0
sly==0.4
smmap==4.0.0
sniffio==1.2.0
snowballstemmer==2.1.0
sortedcontainers==2.4.0
sounddevice==0.4.1
speedtest-cli==2.1.3
Sphinx==3.5.4
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==1.0.3
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.4
Suplemon==0.2.1
tempora==4.0.2
termcolor==1.1.0
terminado==0.9.5
testpath==0.5.0
text-unidecode==1.3
textdistance==4.2.1
thonny==3.3.11
thonnyapp==0.9.1
three-merge==0.1.1
tinycss2==1.1.0
tkcode==0.1.3
tkinterhtml==0.7
tkinterweb==3.9.7
tksheet==5.0.27
tkterminal==0.1.0b1
toml==0.10.2
tornado==6.1
tqdm==4.61.2
traitlets==5.0.5
tui==1.1.1
twine==3.4.1
typed-ast==1.4.3
typing-extensions==3.10.0.0
ujson @ file:///C:/Users/Lenovo/Downloads/ujson-4.0.2-cp38-cp38-win32.whl
UNKNOWN==0.0.0
urllib3==1.26.6
urwid==2.1.2
vaitk==1.7
virtualenv==20.4.6
visvis==1.13.0
watchdog==2.1.3
wcwidth==0.2.5
wday @ file:///E:/Sapphire/Programming/Python%20Modules/WDay
webencodings==0.5.1
webruntime==0.5.8
websocket-client==1.0.0
whichcraft==0.6.1
whirlcalc==2.1
whirldata==1.0
windows-curses==2.2.0
wrapt==1.12.1
wxPython==4.1.1
yapf==0.31.0
Yapsy==1.12.2
yarg==0.1.9
zc.lockfile==2.0
zipp==3.4.1
zope.event==4.5.0
zope.interface==5.4.0
```



>  no, but when i have kivy, then the program.. that i expect to be 20mb in size became 132mb in size..

If you want a minimal build, create a virtual environment and install only the packages that your program really requires. With environment like the one listed above, all sort of packages may end up getting pulled it due to conditional imports...

At any rate, I think I see what the problem is. You uninstalled `kivy`, but you still have `kivymd` installed, and that one also registers a PyInstaller hook (and depends on `kivy`, so trying to load hook entry point fails). 

But ultimately, PyInstaller should handle such situations by catching the exception, otherwise a single mis-configured package can bring down the whole build process (even if it is unused)...
yeah.. i later tried uninstalling a few packages.. then the size reduced to 78mb..

Resolving patch:
diff --git a/PyInstaller/building/build_main.py b/PyInstaller/building/build_main.py
--- a/PyInstaller/building/build_main.py
+++ b/PyInstaller/building/build_main.py
@@ -46,6 +46,7 @@
 from PyInstaller.archive import pyz_crypto
 from PyInstaller.utils.misc import \
     get_path_to_toplevel_modules, get_unicode_modules, mtime
+from PyInstaller.utils.hooks import exec_statement
 
 if is_win:
     from PyInstaller.utils.win32 import winmanifest
@@ -99,6 +100,45 @@ def setupUPXFlags():
     compat.setenv("UPX", f)
 
 
+def discover_hook_directories():
+    """
+    Discover hook directories via pkg_resources and pyinstaller40
+    entry points. Perform the discovery in a subprocess to avoid
+    importing the package(s) in the main process.
+
+    :return: list of discovered hook directories.
+    """
+
+    hook_directories = []
+    output = exec_statement("""
+        import sys
+        import pkg_resources
+
+        entry_points = pkg_resources.iter_entry_points(
+            'pyinstaller40', 'hook-dirs')
+        for entry_point in entry_points:
+            try:
+                hook_dirs = entry_point.load()()
+                for hook_dir in hook_dirs:
+                    print('\\n$_pyi:' + hook_dir + '*')
+            except Exception as e:
+                print("discover_hook_directories: Failed to process hook "
+                      "entry point '%s': %s" % (entry_point, e),
+                      file=sys.stderr)
+    """)
+
+    for line in output.split():
+        # Filter out extra output by checking for the special prefix
+        # and suffix
+        if line.startswith("$_pyi:") and line.endswith("*"):
+            hook_directories.append(line[6:-1])
+
+    logger.debug("discover_hook_directories: Hook directories: %s",
+                 hook_directories)
+
+    return hook_directories
+
+
 class Analysis(Target):
     """
     Class does analysis of the user's main Python scripts.
@@ -215,9 +255,7 @@ def __init__(self, scripts, pathex=None, binaries=None, datas=None,
             self.hookspath.extend(hookspath)
 
         # Add hook directories from PyInstaller entry points.
-        for entry_point in pkg_resources.iter_entry_points(
-                'pyinstaller40', 'hook-dirs'):
-            self.hookspath += list(entry_point.load()())
+        self.hookspath += discover_hook_directories()
 
         self.hooksconfig = {}
         if hooksconfig:


Test patch: