yt-dlp: Broken Cryptodome Import

DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

  • I understand that I will be blocked if I remove or skip any mandatory* field

Checklist

  • I’m reporting a bug unrelated to a specific site
  • I’ve verified that I’m running yt-dlp version 2023.01.06 (update instructions) or later (specify commit)
  • I’ve checked that all provided URLs are playable in a browser with the same IP and same login details
  • I’ve checked that all URLs and arguments with special characters are properly quoted or escaped
  • I’ve searched the bugtracker for similar issues including closed ones. DO NOT post duplicates
  • I’ve read the guidelines for opening an issue

Provide a description that is worded well enough to be understood

yt-dlp no longer works after building with pyinstall, tested in linux and windows

Provide verbose output that clearly demonstrates the problem

  • Run your yt-dlp command with -vU flag added (yt-dlp -vU <your command line>)
  • Copy the WHOLE output (starting with [debug] Command-line config) and insert it below

Complete Verbose Output

Traceback (most recent call last):
  File "yt_dlp\compat\compat_utils.py", line 50, in __getattribute__
  File "yt_dlp\compat\compat_utils.py", line 72, in __getattr__
AttributeError: module yt_dlp.dependencies.Cryptodome.Cipher has no attribute AES

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "yt_dlp\__main__.py", line 14, in <module>
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
  File "yt_dlp\__init__.py", line 18, in <module>
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
  File "yt_dlp\cookies.py", line 18, in <module>
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
  File "yt_dlp\aes.py", line 5, in <module>
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
  File "yt_dlp\dependencies\__init__.py", line 76, in <module>
  File "yt_dlp\compat\compat_utils.py", line 57, in __getattribute__
  File "yt_dlp\compat\compat_utils.py", line 72, in __getattr__
AttributeError: module yt_dlp.dependencies.Cryptodome.Cipher has no attribute AES
[22924] Failed to execute script '__main__' due to unhandled exception!

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 22 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks. I was getting frustrated with none of the reporters being willing to provide this info. My guess in https://github.com/yt-dlp/yt-dlp/issues/6272#issuecomment-1435433009 is almost correct, but it’s pycrypto, not cryptodomex that’s broken. Older yt-dlp versions were ignoring the error silently. The patch in that comment should work around the issue for now.

Since pycrypto is no longer being maintained, It’s on us to handle it. The “proper” solution is for users to replace pycrypto with the newer pycryptodomex. But not everyone can, wants to, or is able to do so. I’ll make yt-dlp detect this issue and ignore the package instead

We are in fact packing more than needed, i.e. all of pycryptodome instead of just the submodules we want. This is done so we don’t have to explicitly define what we want and what we don’t. I don’t think a 1.5M increase is worth reverting it over.

If you are really concerned about the filesize, you’d have to manually maintain a list

diff --git a/yt_dlp/__pyinstaller/hook-yt_dlp.py b/yt_dlp/__pyinstaller/hook-yt_dlp.py
index 66d1b6369..f6ae075dc 100644
--- a/yt_dlp/__pyinstaller/hook-yt_dlp.py
+++ b/yt_dlp/__pyinstaller/hook-yt_dlp.py
@@ -19,8 +19,17 @@ def _pycryptodome_module():

 def _hidden_imports():
     yield 'yt_dlp.compat._legacy'
-    for m in [_pycryptodome_module(), 'websockets']:
+    for m in ['websockets']:
         yield from collect_submodules(m)
+    yield from [
+        'Cryptodome.Cipher.AES',
+        'Cryptodome.Cipher.Blowfish',
+        'Cryptodome.Cipher.PKCS1_OAEP',
+        'Cryptodome.Cipher.PKCS1_v1_5',
+        'Cryptodome.Hash.CMAC',
+        'Cryptodome.Hash.SHA1',
+        'Cryptodome.PublicKey.RSA',
+    ]
     # These are auto-detected, but explicitly add them just in case
     yield from ('mutagen', 'brotli', 'certifi')

PS: Even previously, we are packing some modules that we don’t need in base_library.zip

Greetings 😄 !

My building environment relies on CPython 3.7.16 (32-bit), on a 32-bit Windows OS 😉 …

python -m pip list reports:

Package                   Version
------------------------- ---------
altgraph                  0.17.3
Brotli                    1.0.9
certifi                   2022.12.7
future                    0.18.3
importlib-metadata        6.0.0
mutagen                   1.46.0
pefile                    2023.2.7
pip                       23.0
pycryptodomex             3.17
pyinstaller               5.7.0
pyinstaller-hooks-contrib 2022.15
pywin32-ctypes            0.2.0
setuptools                67.2.0
typing_extensions         4.4.0
websockets                10.4
wheel                     0.38.4
zipp                      3.12.1

When I compile source snapshot yt-dlp-2023.01.06-26-git-20230208-g754c84e (immediately previous to f6a765c), the compilation (of course) succeeds, the resultant yt-dlp_x86.exe binary has a file size of ca. 11.7 MiB

OTOH, when I compile latest master HEAD, snapshot yt-dlp-2023.01.06-36-git-20230208-gf14c233, the compilation (now) succeeds (due to recent fix), however the file size of the resultant yt-dlp_x86.exe binary comes at ca. 13.2 MiB, i.e. a significant 12.82% size increase (I can provide PyInstaller compilation logs, if asked) …

Is that something to be expected because of f6a765c, or are we somehow packing “more” than needed? …

Thanks in advance 😺 …

Same here on Windows 10 with Python 3.11.1. Running yt-dlp.cmd -v gives no error.

On Linux there is no issue with the compiled yt-dlp:

./yt-dlp --ignore-config -v
[debug] Command-line config: ['--ignore-config', '-v']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version 2023.02.08 [f40e32fb1] (zip)
[debug] Python 3.8.10 (CPython x86_64 64bit) - Linux-5.4.0-137-generic-x86_64-with-glibc2.29 (OpenSSL 1.1.1f  31 Mar 2020, glibc 2.31)
[debug] exe versions: ffmpeg N-109587-gfc263f073e-Nico-20230113 (fdk,setts), ffprobe N-109587-gfc263f073e-Nico-20230113, phantomjs 2.1.1, rtmpdump 2.4
[debug] Optional libraries: Cryptodome-3.17, brotli-1.0.9, certifi-2022.12.07, mutagen-1.46.0, secretstorage-3.3.3, sqlite3-2.6.0, websockets-10.4, xattr-0.9.6
[debug] Proxy map: {}
[debug] Loaded 1766 extractors

Usage: yt-dlp [OPTIONS] URL [URL...]

yt-dlp: error: You must provide at least one URL.
Type yt-dlp --help to see a list of all options.

I pretty much followed instructions from readme. First created venv Then ran the following

python3 -m pip install -U pyinstaller -r requirements.txt
python3 devscripts/make_lazy_extractors.py
python3 pyinst.py

I’m on this commit commit f40e32fb1ac67be5bdbc8e32a3c235abfc4be260 (HEAD -> master, origin/master, origin/HEAD)

Can’t post any useful log as app crashes even without any args.

List of packages

Package                   Version
------------------------- ---------
altgraph                  0.17.3
Brotli                    1.0.9
certifi                   2022.12.7
mutagen                   1.46.0
pip                       23.0
pycryptodomex             3.17
pyinstaller               5.7.0
pyinstaller-hooks-contrib 2022.15
setuptools                65.6.3
websockets                10.4
wheel                     0.38.4

Edit: executing yt-dlp.sh seems to work fine