diff --git a/.github/workflows/pr-test.yml b/.github/workflows/pr-test.yml index 31665b1f..a9356952 100644 --- a/.github/workflows/pr-test.yml +++ b/.github/workflows/pr-test.yml @@ -86,6 +86,8 @@ jobs: libpulse0 libpulse-mainloop-glib0 # Install cairo dependencies. sudo apt-get install -y libcairo2 + # Install libdiscid (dependency of discid python package). + sudo apt-get install -y libdiscid0 - name: Install brew dependencies if: startsWith(matrix.os, 'macos') @@ -94,6 +96,8 @@ jobs: brew install cairo # Install pango dependencies (weasyprint hook). brew install pango + # Install libdiscid (dependency of discid python package). + brew install libdiscid - name: Install dependencies shell: bash diff --git a/news/506.new.rst b/news/506.new.rst new file mode 100644 index 00000000..4f6591d8 --- /dev/null +++ b/news/506.new.rst @@ -0,0 +1 @@ +Add hook for ``discid``. diff --git a/requirements-test-libraries.txt b/requirements-test-libraries.txt index 562a2588..60873ff6 100644 --- a/requirements-test-libraries.txt +++ b/requirements-test-libraries.txt @@ -18,6 +18,9 @@ cloudscraper==1.2.64 dash==2.6.2 dash-bootstrap-components==1.2.1 dash-uploader==0.6.0 +# discid requires libdiscid to be provided by the system. +# We install it via apt-get and brew on ubuntu and macOS CI runners, respectively. +discid==1.2.0; sys_platform != 'win32' fabric==2.7.1 fiona==1.8.22; sys_platform != 'win32' folium==0.13.0 diff --git a/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-discid.py b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-discid.py new file mode 100644 index 00000000..e2a587e2 --- /dev/null +++ b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-discid.py @@ -0,0 +1,41 @@ +# ------------------------------------------------------------------ +# Copyright (c) 2022 PyInstaller Development Team. +# +# This file is distributed under the terms of the GNU General Public +# License (version 2.0 or later). +# +# The full license is available in LICENSE.GPL.txt, distributed with +# this software. +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ------------------------------------------------------------------ + +import os + +from PyInstaller.utils.hooks import get_module_attribute, logger +from PyInstaller.depend.utils import _resolveCtypesImports + + +binaries = [] + +# Use the _LIB_NAME attribute of discid.libdiscid to resolve the shared library name. This saves us from having to +# duplicate the name guessing logic from discid.libdiscid. +# On error, PyInstaller >= 5.0 raises exception, earlier versions return an empty string. +try: + lib_name = get_module_attribute("discid.libdiscid", "_LIB_NAME") +except Exception: + lib_name = None + +if lib_name: + lib_name = os.path.basename(lib_name) + try: + resolved_binary = _resolveCtypesImports([lib_name]) + lib_file = resolved_binary[0][1] + except Exception as e: + lib_file = None + logger.warning("Error while trying to resolve %s: %s", lib_name, e) + + if lib_file: + binaries += [(lib_file, '.')] +else: + logger.warning("Failed to determine name of libdiscid shared library from _LIB_NAME attribute of discid.libdiscid!") diff --git a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py index 2bb4f256..87eca7b5 100644 --- a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py +++ b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py @@ -1385,3 +1385,21 @@ def test_spiceypy(pyi_builder): pyi_builder.test_source(""" import spiceypy """) + + +@importorskip('discid') +def test_discid(pyi_builder): + pyi_builder.test_source( + """ + # Basic import check + import discid + + # Check that shared library is in fact collected into application bundle. + # We expect the hook to collect it to top-level directory (sys._MEIPASS). + import discid.libdiscid + lib_name = discid.libdiscid._LIB_NAME + + lib_file = os.path.join(sys._MEIPASS, lib_name) + assert os.path.isfile(lib_file), f"Shared library {lib_name} not collected to _MEIPASS!" + """ + )