diff --git a/news/760.update.rst b/news/760.update.rst new file mode 100644 index 000000000..1786fde14 --- /dev/null +++ b/news/760.update.rst @@ -0,0 +1,8 @@ +Update ``hydra`` hook to include work-around for ``hydra``'s plugin +manager, which under python < 3.10 (still) uses deprecated PEP-302 +that was removed from PyInstaller's ``PyiFrozenImporter`` in +PyInstaller 5.8. When building using python < 3.10 and PyInstaller >= 5.8, +the modules collected from ``hydra._internal.core_plugins`` and +``hydra_plugins`` packages are now collected as source .py files only; +this way, they are handled by built-in python's finder/importer instead +of PyInstaller's ``PyiFrozenImporter``. diff --git a/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-hydra.py b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-hydra.py index 58e7673fb..0c6197788 100644 --- a/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-hydra.py +++ b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-hydra.py @@ -10,10 +10,27 @@ # SPDX-License-Identifier: GPL-2.0-or-later # ------------------------------------------------------------------ -from PyInstaller.utils.hooks import collect_submodules, collect_data_files +from PyInstaller.compat import is_py310 +from PyInstaller.utils.hooks import collect_submodules, collect_data_files, is_module_satisfies # Collect core plugins. hiddenimports = collect_submodules('hydra._internal.core_plugins') +# Hydra's plugin manager (`hydra.core.plugins.Plugins`) uses PEP-302 `find_module` / `load_module`, which has been +# deprecated since python 3.4, and has been removed from PyInstaller's frozen importer in PyInstaller 5.8. For python +# 3.10 and newer, they implemented new codepath that uses `find_spec`, but for earlier python versions, they opted to +# keep using the old codepath. +# +# See: https://github.com/facebookresearch/hydra/pull/2531 +# +# To work around the incompatibility with PyInstaller >= 5.8 when using python < 3.10, force collection of plugins as +# source .py files. This way, they end up handled by python's built-in finder/importer instead of PyInstaller's +# frozen importer. +if not is_py310 and is_module_satisfies("PyInstaller >= 5.8"): + module_collection_mode = { + 'hydra._internal.core_plugins': 'py', + 'hydra_plugins': 'py', + } + # Collect package's data files, such as default configuration files. datas = collect_data_files('hydra') diff --git a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py index e37768440..4f746b624 100644 --- a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py +++ b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py @@ -1309,11 +1309,7 @@ def test_pyqtgraph_remote_graphics_view(pyi_builder): ) -# Remove xfail once facebookresearch/hydra#2531 is merged. @importorskip('hydra') -@xfail( - is_module_satisfies('PyInstaller >= 5.8'), - reason="uses deprecated PEP-302 functionality that was removed from PyInstaller's FrozenImporter.") def test_hydra(pyi_builder, tmpdir): config_file = str((Path(__file__) / '../data/test_hydra/config.yaml').resolve(strict=True).as_posix())