Skip to content

Commit

Permalink
hooks: hydra: add work-around for python < 3.10 and PyInstaller >= 5.8
Browse files Browse the repository at this point in the history
Under python < 3.10, `hydra`'s plugin manager continues to use
deprecated PEP-302 functionality that was removed from PyInstaller's
`PyiFrozenImporter` in PyInstaller 5.8 (pyinstaller/pyinstaller#7344.).
At run-time, this results in `AttributeError: 'PyiFrozenImporter'
object has no attribute 'find_module'`.

As a work-around, check python version and PyInstaller version,
and if using python < 3.10 and PyInstaller >= 5.8, set module
collection mode for `hydra._internal.core_plugins` and
`hydra_plugins` packages to `py` to collect their modules as
source .py files only. This way, they end up handled by python's
built-in finder/importer, instead of PyInstaller's `PyiFrozenImporter`.
  • Loading branch information
rokm committed Jul 12, 2024
1 parent 4e2c4b3 commit 2d3b566
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
8 changes: 8 additions & 0 deletions news/760.update.rst
Original file line number Diff line number Diff line change
@@ -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``.
19 changes: 18 additions & 1 deletion src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-hydra.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
4 changes: 0 additions & 4 deletions src/_pyinstaller_hooks_contrib/tests/test_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand Down

0 comments on commit 2d3b566

Please # to comment.