Skip to content

Commit

Permalink
hooks: clr: on non-Windows, collect Python.Runtime.dll as a data file
Browse files Browse the repository at this point in the history
Collecting it as a binary causes errors during binary dependency
analysis on macOS (and likely causes warnings on linux) due to
incompatible binary format.
  • Loading branch information
rokm committed Oct 19, 2022
1 parent 31ac153 commit 981228a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
3 changes: 3 additions & 0 deletions news/500.update.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In ``clr`` hook for ``pythonnet`` collect the ``Python.Runtime.dll`` as
a data file on non-Windows OSes to prevent errors during binary dependency
analysis.
18 changes: 13 additions & 5 deletions src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-clr.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# the terminal styling library (https://pypi.org/project/clr/). Therefore, we must first check if pythonnet is actually
# available...
from PyInstaller.utils.hooks import is_module_satisfies
from PyInstaller.compat import is_win


if is_module_satisfies("pythonnet"):
Expand All @@ -27,28 +28,35 @@
except ImportError:
import importlib_metadata

binaries = []
collected_runtime_files = []

# Try finding Python.Runtime.dll via distribution's file list
dist_files = importlib_metadata.files('pythonnet')
if dist_files is not None:
runtime_dll_files = [f for f in dist_files if f.match('Python.Runtime.dll')]
if len(runtime_dll_files) == 1:
runtime_dll_file = runtime_dll_files[0]
binaries = [(runtime_dll_file.locate(), runtime_dll_file.parent.as_posix())]
collected_runtime_files = [(runtime_dll_file.locate(), runtime_dll_file.parent.as_posix())]
logger.debug("hook-clr: Python.Runtime.dll discovered via metadata.")
elif len(runtime_dll_files) > 1:
logger.warning("hook-clr: multiple instances of Python.Runtime.dll listed in metadata - cannot resolve.")

# Fall back to the legacy way
if not binaries:
if not collected_runtime_files:
runtime_dll_file = ctypes.util.find_library('Python.Runtime')
if runtime_dll_file:
binaries = [(runtime_dll_file, '.')]
collected_runtime_files = [(runtime_dll_file, '.')]
logger.debug('hook-clr: Python.Runtime.dll discovered via legacy method.')

if not binaries:
if not collected_runtime_files:
raise Exception('Python.Runtime.dll not found')

# On Windows, collect runtime DLL file(s) as binaries; on other OSes, collect them as data files, to prevent fatal
# errors in binary dependency analysis.
if is_win:
binaries = collected_runtime_files
else:
datas = collected_runtime_files

# These modules are imported inside Python.Runtime.dll
hiddenimports = ["platform", "warnings"]

0 comments on commit 981228a

Please sign in to comment.