diff --git a/news/675.update.rst b/news/675.update.rst new file mode 100644 index 00000000..4d3ed468 --- /dev/null +++ b/news/675.update.rst @@ -0,0 +1,3 @@ +Update hook for ``skimage.feature`` to collect the +``orb_descriptor_positions.txt`` data file, which is required by +the ``skimage.feature.ORB`` class. diff --git a/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-skimage.feature.py b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-skimage.feature.py index eb7b8b62..538f055c 100644 --- a/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-skimage.feature.py +++ b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-skimage.feature.py @@ -15,8 +15,12 @@ # The following missing module prevents import of skimage.feature with skimage 0.17.x. hiddenimports = ['skimage.feature._orb_descriptor_positions', ] +# Collect the data file with ORB descriptor positions. In earlier versions of scikit-image, this file was in +# `skimage/data` directory, and it was moved to `skimage/feature` in v0.17.0. Collect if from wherever it is. +datas = collect_data_files('skimage', includes=['**/orb_descriptor_positions.txt']) + # As of scikit-image 0.22.0, we need to collect the __init__.pyi file for `lazy_loader`, as well as collect submodules # due to lazy loading. if is_module_satisfies("scikit-image >= 0.22.0"): - datas = collect_data_files("skimage.feature", includes=["*.pyi"]) + datas += collect_data_files("skimage.feature", includes=["*.pyi"]) hiddenimports = collect_submodules('skimage.feature', filter=lambda name: name != 'skimage.feature.tests') diff --git a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py index daee18a4..7841dbf6 100644 --- a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py +++ b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py @@ -489,43 +489,6 @@ def test_pydivert(pyi_builder): """) -@pytest.mark.slow -@importorskip('skimage') -@pytest.mark.skipif(not is_module_satisfies('scikit_image >= 0.16'), - reason='The test supports only scikit-image >= 0.16.') -@pytest.mark.parametrize('submodule', [ - 'color', 'data', 'draw', 'exposure', 'feature', 'filters', 'future', - 'graph', 'io', 'measure', 'metrics', 'morphology', 'registration', - 'restoration', 'segmentation', 'transform', 'util' -]) -def test_skimage(pyi_builder, submodule): - pyi_builder.test_source(""" - import skimage.{0} - """.format(submodule)) - - -@pytest.mark.slow -@importorskip('sklearn') -@pytest.mark.skipif(not is_module_satisfies('scikit_learn >= 0.21'), - reason='The test supports only scikit-learn >= 0.21.') -@pytest.mark.parametrize('submodule', [ - 'calibration', 'cluster', 'covariance', 'cross_decomposition', - 'datasets', 'decomposition', 'dummy', 'ensemble', 'exceptions', - 'experimental', 'externals', 'feature_extraction', - 'feature_selection', 'gaussian_process', 'inspection', - 'isotonic', 'kernel_approximation', 'kernel_ridge', - 'linear_model', 'manifold', 'metrics', 'mixture', - 'model_selection', 'multiclass', 'multioutput', - 'naive_bayes', 'neighbors', 'neural_network', 'pipeline', - 'preprocessing', 'random_projection', 'semi_supervised', - 'svm', 'tree', 'discriminant_analysis', 'impute', 'compose' -]) -def test_sklearn(pyi_builder, submodule): - pyi_builder.test_source(""" - import sklearn.{0} - """.format(submodule)) - - @importorskip('statsmodels') @pytest.mark.skipif(not is_module_satisfies('statsmodels >= 0.12'), reason='This has only been tested with statsmodels >= 0.12.') diff --git a/src/_pyinstaller_hooks_contrib/tests/test_scikit_image.py b/src/_pyinstaller_hooks_contrib/tests/test_scikit_image.py new file mode 100644 index 00000000..2513d5a5 --- /dev/null +++ b/src/_pyinstaller_hooks_contrib/tests/test_scikit_image.py @@ -0,0 +1,70 @@ +# ------------------------------------------------------------------ +# Copyright (c) 2020 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 pytest + +from PyInstaller.utils.hooks import is_module_satisfies +from PyInstaller.utils.tests import importorskip + + +# Run the tests in onedir mode only +onedir_only = pytest.mark.parametrize('pyi_builder', ['onedir'], indirect=True) + + +# Basic import tests for sub-packages of skimage. Run only on demand, and only in onedir mode. +@pytest.mark.slow +@onedir_only +@importorskip('skimage') +@pytest.mark.skipif( + not is_module_satisfies('scikit_image >= 0.16'), + reason='The test supports only scikit-image >= 0.16.', +) +@pytest.mark.parametrize('submodule', [ + 'color', 'data', 'draw', 'exposure', 'feature', 'filters', 'future', + 'graph', 'io', 'measure', 'metrics', 'morphology', 'registration', + 'restoration', 'segmentation', 'transform', 'util' +]) +def test_skimage(pyi_builder, submodule): + pyi_builder.test_source(""" + import skimage.{0} + """.format(submodule)) + + +# Test the ORB descriptor, which requires the data file with descriptor sample points. +@importorskip('skimage') +def test_skimage_feature_orb(pyi_builder): + pyi_builder.test_source(""" + import skimage.feature + import numpy as np + + # Prepare test images + img1 = np.zeros((100, 100)) + img2 = np.zeros_like(img1) + rng = np.random.default_rng(1984) + square = rng.random((20, 20)) + img1[40:60, 40:60] = square + img2[53:73, 53:73] = square + + # ORB detector/descriptor extractor + detector_extractor1 = skimage.feature.ORB(n_keypoints=5) + detector_extractor2 = skimage.feature.ORB(n_keypoints=5) + + # Process + detector_extractor1.detect_and_extract(img1) + detector_extractor2.detect_and_extract(img2) + + matches = skimage.feature.match_descriptors( + detector_extractor1.descriptors, + detector_extractor2.descriptors, + ) + print(matches) + """) diff --git a/src/_pyinstaller_hooks_contrib/tests/test_scikit_learn.py b/src/_pyinstaller_hooks_contrib/tests/test_scikit_learn.py new file mode 100644 index 00000000..47731944 --- /dev/null +++ b/src/_pyinstaller_hooks_contrib/tests/test_scikit_learn.py @@ -0,0 +1,46 @@ +# ------------------------------------------------------------------ +# Copyright (c) 2020 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 pytest + +from PyInstaller.utils.hooks import is_module_satisfies +from PyInstaller.utils.tests import importorskip + + +# Run the tests in onedir mode only +onedir_only = pytest.mark.parametrize('pyi_builder', ['onedir'], indirect=True) + + +# Basic import tests for sub-packages of sklearn. Run only on demand, and only in onedir mode. +@pytest.mark.slow +@onedir_only +@importorskip('sklearn') +@pytest.mark.skipif( + not is_module_satisfies('scikit_learn >= 0.21'), + reason='The test supports only scikit-learn >= 0.21.', +) +@pytest.mark.parametrize('submodule', [ + 'calibration', 'cluster', 'covariance', 'cross_decomposition', + 'datasets', 'decomposition', 'dummy', 'ensemble', 'exceptions', + 'experimental', 'externals', 'feature_extraction', + 'feature_selection', 'gaussian_process', 'inspection', + 'isotonic', 'kernel_approximation', 'kernel_ridge', + 'linear_model', 'manifold', 'metrics', 'mixture', + 'model_selection', 'multiclass', 'multioutput', + 'naive_bayes', 'neighbors', 'neural_network', 'pipeline', + 'preprocessing', 'random_projection', 'semi_supervised', + 'svm', 'tree', 'discriminant_analysis', 'impute', 'compose' +]) +def test_sklearn(pyi_builder, submodule): + pyi_builder.test_source(""" + import sklearn.{0} + """.format(submodule))