hook-enchant.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. Import hook for PyEnchant.
  14. Tested with PyEnchant 1.6.6.
  15. """
  16. import os
  17. from PyInstaller import isolated
  18. from PyInstaller import compat
  19. from PyInstaller.utils.hooks import collect_data_files, collect_dynamic_libs, get_installer
  20. # TODO Add Linux support
  21. # Collect first all files that were installed directly into pyenchant
  22. # package directory and this includes:
  23. # - Windows: libenchat-1.dll, libenchat_ispell.dll, libenchant_myspell.dll, other
  24. # dependent dlls and dictionaries for several languages (de, en, fr)
  25. # - macOS: usually libenchant.dylib and several dictionaries when installed via pip.
  26. binaries = collect_dynamic_libs('enchant')
  27. datas = collect_data_files('enchant')
  28. excludedimports = ['enchant.tests']
  29. # On macOS try to find files in Homebrew or Macports environments.
  30. if compat.is_darwin:
  31. # Note: env. var. ENCHANT_PREFIX_DIR is implemented only in the development version:
  32. # https://github.com/AbiWord/enchant
  33. # https://github.com/AbiWord/enchant/pull/2
  34. # TODO Test this hook with development version of enchant.
  35. @isolated.decorate
  36. def _get_enchant_lib():
  37. from enchant._enchant import e # ctypes.CDLL
  38. return e._name
  39. libenchant = _get_enchant_lib()
  40. installer = get_installer('enchant')
  41. if installer != 'pip':
  42. # Note: Name of detected enchant library is 'libenchant.dylib'. However, it
  43. # is just symlink to 'libenchant.1.dylib'.
  44. binaries.append((libenchant, '.'))
  45. # Collect enchant backends from Macports. Using same file structure as on Windows.
  46. @isolated.decorate
  47. def _get_enchant_backends():
  48. from enchant import Broker
  49. return [str(provider.file) for provider in Broker().describe()]
  50. backends = _get_enchant_backends()
  51. binaries.extend([(b, 'enchant/lib/enchant') for b in backends])
  52. # Collect all available dictionaries from Macports. Using same file structure as on Windows.
  53. # In Macports are available mostly hunspell (myspell) and aspell dictionaries.
  54. libdir = os.path.dirname(libenchant) # e.g. /opt/local/lib
  55. sharedir = os.path.join(os.path.dirname(libdir), 'share') # e.g. /opt/local/share
  56. if os.path.exists(os.path.join(sharedir, 'enchant')):
  57. datas.append((os.path.join(sharedir, 'enchant'), 'enchant/share/enchant'))
  58. if os.path.exists(os.path.join(sharedir, 'enchant-2')):
  59. datas.append((os.path.join(sharedir, 'enchant-2'), 'enchant/share/enchant-2'))