hook-Crypto.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. # ------------------------------------------------------------------
  2. # Copyright (c) 2020 PyInstaller Development Team.
  3. #
  4. # This file is distributed under the terms of the GNU General Public
  5. # License (version 2.0 or later).
  6. #
  7. # The full license is available in LICENSE, distributed with
  8. # this software.
  9. #
  10. # SPDX-License-Identifier: GPL-2.0-or-later
  11. # ------------------------------------------------------------------
  12. """
  13. Hook for PyCryptodome library: https://pypi.python.org/pypi/pycryptodome
  14. PyCryptodome is an almost drop-in replacement for the now unmaintained
  15. PyCrypto library. The two are mutually exclusive as they live under
  16. the same package ("Crypto").
  17. PyCryptodome distributes dynamic libraries and builds them as if they were
  18. Python C extensions (even though they are not extensions - as they can't be
  19. imported by Python). It might sound a bit weird, but this decision is rooted
  20. in PyPy and its partial and slow support for C extensions. However, this also
  21. invalidates several of the existing methods used by PyInstaller to decide the
  22. right files to pull in.
  23. Even though this hook is meant to help with PyCryptodome only, it will be
  24. triggered also when PyCrypto is installed, so it must be tested with both.
  25. Tested with PyCryptodome 3.5.1, PyCrypto 2.6.1, Python 2.7 & 3.6, Fedora & Windows
  26. """
  27. import os
  28. import glob
  29. from PyInstaller.compat import EXTENSION_SUFFIXES
  30. from PyInstaller.utils.hooks import get_module_file_attribute
  31. # Include the modules as binaries in a subfolder named like the package.
  32. # Cryptodome's loader expects to find them inside the package directory for
  33. # the main module. We cannot use hiddenimports because that would add the
  34. # modules outside the package.
  35. binaries = []
  36. binary_module_names = [
  37. 'Crypto.Math', # First in the list
  38. 'Crypto.Cipher',
  39. 'Crypto.Util',
  40. 'Crypto.Hash',
  41. 'Crypto.Protocol',
  42. 'Crypto.PublicKey',
  43. ]
  44. try:
  45. for module_name in binary_module_names:
  46. m_dir = os.path.dirname(get_module_file_attribute(module_name))
  47. for ext in EXTENSION_SUFFIXES:
  48. module_bin = glob.glob(os.path.join(m_dir, '_*%s' % ext))
  49. for f in module_bin:
  50. binaries.append((f, module_name.replace('.', os.sep)))
  51. except ImportError:
  52. # Do nothing for PyCrypto (Crypto.Math does not exist there)
  53. pass