diff --git a/tests/functional/scripts/pkg_resource_res_string.py b/tests/functional/scripts/pkg_resource_res_string.py deleted file mode 100644 index 74539e70de..0000000000 --- a/tests/functional/scripts/pkg_resource_res_string.py +++ /dev/null @@ -1,26 +0,0 @@ -#----------------------------------------------------------------------------- -# Copyright (c) 2013-2023, PyInstaller Development Team. -# -# Distributed under the terms of the GNU General Public License (version 2 -# or later) with exception for distributing the bootloader. -# -# The full license is in the file COPYING.txt, distributed with this software. -# -# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception) -#----------------------------------------------------------------------------- - -# With module 'pkg_resources' it should not matter if a file is stored on file system, in zip archive or bundled with -# frozen app. -import pkg_resources as res -import pkg3 - -expected_data = 'This is data text for testing the packaging module data.'.encode('ascii') - -# In a frozen app, the resources is available at: os.path.join(sys._MEIPASS, 'pkg3/sample-data.txt') -data = res.resource_string(pkg3.__name__, 'sample-data.txt') -if not data: - raise SystemExit('Error: Could not read data with pkgutil.get_data().') - -if data.strip() != expected_data: - raise SystemExit('Error: Read data is wrong: %r' % data) -print('Okay: Resource data read.') diff --git a/tests/functional/scripts/pkgutil_get_data.py b/tests/functional/scripts/pkgutil_get_data.py deleted file mode 100644 index ebb02a8337..0000000000 --- a/tests/functional/scripts/pkgutil_get_data.py +++ /dev/null @@ -1,24 +0,0 @@ -#----------------------------------------------------------------------------- -# Copyright (c) 2013-2023, PyInstaller Development Team. -# -# Distributed under the terms of the GNU General Public License (version 2 -# or later) with exception for distributing the bootloader. -# -# The full license is in the file COPYING.txt, distributed with this software. -# -# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception) -#----------------------------------------------------------------------------- - -import pkgutil - -import pkg3 # noqa: F401 - -expected_data = 'This is data text for testing the packaging module data.'.encode('ascii') - -data = pkgutil.get_data('pkg3', 'sample-data.txt') -if not data: - raise SystemExit('Error: Could not read data with pkgutil.get_data().') - -if data.strip() != expected_data: - raise SystemExit('Error: Read data is wrong: %r' % data) -print('Okay: Resource data read.') diff --git a/tests/functional/scripts/pkgutil_get_data__main__.py b/tests/functional/scripts/pkgutil_get_data__main__.py deleted file mode 100644 index cbcbea9558..0000000000 --- a/tests/functional/scripts/pkgutil_get_data__main__.py +++ /dev/null @@ -1,22 +0,0 @@ -#----------------------------------------------------------------------------- -# Copyright (c) 2013-2023, PyInstaller Development Team. -# -# Distributed under the terms of the GNU General Public License (version 2 -# or later) with exception for distributing the bootloader. -# -# The full license is in the file COPYING.txt, distributed with this software. -# -# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception) -#----------------------------------------------------------------------------- - -import pkgutil - -expected_data = 'This is data text for testing the packaging module data.'.encode('ascii') - -data = pkgutil.get_data('__main__', 'pkg3/sample-data.txt') -if not data: - raise SystemExit('Error: Could not read data with pkgutil.get_data().') - -if data.strip() != expected_data: - raise SystemExit('Error: Read data is wrong: %r' % data) -print('Okay: Resource data read.') diff --git a/tests/functional/scripts/pyi_lib_PIL_img_conversion.py b/tests/functional/scripts/pyi_lib_PIL_img_conversion.py deleted file mode 100644 index 729e6108cc..0000000000 --- a/tests/functional/scripts/pyi_lib_PIL_img_conversion.py +++ /dev/null @@ -1,23 +0,0 @@ -#----------------------------------------------------------------------------- -# Copyright (c) 2005-2023, PyInstaller Development Team. -# -# Distributed under the terms of the GNU General Public License (version 2 -# or later) with exception for distributing the bootloader. -# -# The full license is in the file COPYING.txt, distributed with this software. -# -# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception) -#----------------------------------------------------------------------------- - -import sys -import os - -import PIL.Image - -# Disable "leaking" the installed version. -PIL.Image.__file__ = '/' - -# Convert tiff to png. -basedir = sys._MEIPASS -im = PIL.Image.open(os.path.join(basedir, "tinysample.tiff")) -im.save(os.path.join(basedir, "tinysample.png")) diff --git a/tests/functional/test_libraries.py b/tests/functional/test_libraries.py index b1ab997ef0..881f828f87 100644 --- a/tests/functional/test_libraries.py +++ b/tests/functional/test_libraries.py @@ -9,18 +9,12 @@ # SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception) #----------------------------------------------------------------------------- -import pathlib - import pytest from PyInstaller.compat import is_win, is_linux -from PyInstaller.utils.tests import importorskip, xfail, skipif, requires +from PyInstaller.utils.tests import importorskip, skipif, requires from PyInstaller.utils.hooks import can_import_module -# :todo: find a way to get this from `conftest` or such directory with testing modules used in some tests. -_MODULES_DIR = pathlib.Path(__file__).parent / 'modules' -_DATA_DIR = pathlib.Path(__file__).parent / 'data' - @importorskip('gevent') def test_gevent(pyi_builder): @@ -117,25 +111,6 @@ def shutdown_timer_callback(): ) -def test_pkg_resource_res_string(pyi_builder, monkeypatch): - # Include some data files for testing pkg_resources module. - add_data_arg = f"{_MODULES_DIR / 'pkg3' / 'sample-data.txt'}:pkg3" - pyi_builder.test_script('pkg_resource_res_string.py', pyi_args=['--add-data', add_data_arg]) - - -def test_pkgutil_get_data(pyi_builder, monkeypatch): - # Include some data files for testing pkg_resources module. - add_data_arg = f"{_MODULES_DIR / 'pkg3' / 'sample-data.txt'}:pkg3" - pyi_builder.test_script('pkgutil_get_data.py', pyi_args=['--add-data', add_data_arg]) - - -@xfail(reason='Our import mechanism returns the wrong loader-class for __main__.') -def test_pkgutil_get_data__main__(pyi_builder, monkeypatch): - # Include some data files for testing pkg_resources module. - add_data_arg = f"{_MODULES_DIR / 'pkg3' / 'sample-data.txt'}:pkg3" - pyi_builder.test_script('pkgutil_get_data__main__.py', pyi_args=['--add-data', add_data_arg]) - - @importorskip('sphinx') def test_sphinx(pyi_builder, data_dir): pyi_builder.test_script( @@ -391,54 +366,6 @@ def test_zeep(pyi_builder): ) -@importorskip('PIL') -#@pytest.mark.xfail(reason="Fails with Pillow 3.0.0") -def test_pil_img_conversion(pyi_builder): - add_data_arg = f"{_DATA_DIR / 'PIL_images'}:." - pyi_builder.test_script( - 'pyi_lib_PIL_img_conversion.py', - pyi_args=[ - '--add-data', add_data_arg, - # Use console mode or else on Windows the VS() messageboxes will stall pytest. - '--console' - ], - ) # yapf: disable - - -@requires("pillow >= 1.1.6") -@importorskip('PyQt5') -def test_pil_PyQt5(pyi_builder): - # hook-PIL is excluding PyQt5, but is must still be included since it is imported elsewhere. - # Also see issue #1584. - pyi_builder.test_source(""" - import PyQt5 - import PIL - import PIL.ImageQt - """) - - -@importorskip('PIL') -def test_pil_plugins(pyi_builder): - pyi_builder.test_source( - """ - # Verify packaging of PIL.Image. - from PIL.Image import frombytes - print(frombytes) - - # PIL import hook should bundle all available PIL plugins. Verify that plugins are collected. - from PIL import Image - Image.init() - MIN_PLUG_COUNT = 7 # Without all plugins the count is usually 6. - plugins = list(Image.SAVE.keys()) - plugins.sort() - if len(plugins) < MIN_PLUG_COUNT: - raise SystemExit('No PIL image plugins were collected!') - else: - print('PIL supported image formats: %s' % plugins) - """ - ) - - @importorskip('pandas') def test_pandas_extension(pyi_builder): # Tests that the C extension ``pandas._libs.lib`` is properly bundled. Issue #1580. diff --git a/tests/functional/test_pil.py b/tests/functional/test_pil.py index 7ca2a4c342..a98b81ed45 100644 --- a/tests/functional/test_pil.py +++ b/tests/functional/test_pil.py @@ -15,15 +15,76 @@ which retains the same Python package `PIL`. """ +import pathlib + import pytest from PyInstaller.utils.tests import importorskip from PyInstaller.utils.hooks import can_import_module +# All tests in this file require PIL +pytestmark = importorskip('PIL') + + +# Functional test that tries to convert a .tiff image to a .png +def test_pil_image_conversion(pyi_builder, tmp_path): + pyi_builder.test_source( + """ + import sys + import os + + import PIL.Image + + if len(sys.argv) != 3: + print(f"use: {sys.argv[0]} ") + raise SystemExit(1) + + input_file = sys.argv[1] + output_file = sys.argv[2] + + image = PIL.Image.open(input_file) + image.save(output_file) + """, + app_args=[ + str(pathlib.Path(__file__).parent / 'data' / 'PIL_images' / 'tinysample.tiff'), + str(tmp_path / 'converted_tinysample.png'), + ], + ) + + +def test_pil_pyqt5(pyi_builder): + # hook-PIL is excluding PyQt5, but is must still be included since it is imported elsewhere. + # Also see issue #1584. + pyi_builder.test_source(""" + import PyQt5 + import PIL + import PIL.ImageQt + """) + + +def test_pil_plugins(pyi_builder): + pyi_builder.test_source( + """ + # Verify packaging of PIL.Image. + from PIL.Image import frombytes + print(frombytes) + + # PIL import hook should bundle all available PIL plugins. Verify that plugins are collected. + from PIL import Image + Image.init() + MIN_PLUG_COUNT = 7 # Without all plugins the count is usually 6. + plugins = list(Image.SAVE.keys()) + plugins.sort() + if len(plugins) < MIN_PLUG_COUNT: + raise SystemExit('No PIL image plugins were collected!') + else: + print('PIL supported image formats: %s' % plugins) + """ + ) + # The tkinter module may be available for import, but not actually importable due to missing shared libraries. # Therefore, we need to use `can_import_module`-based skip decorator instead of `@importorskip`. -@importorskip('PIL') @pytest.mark.skipif(not can_import_module("tkinter"), reason="tkinter cannot be imported.") def test_pil_no_tkinter(pyi_builder): """ @@ -56,7 +117,6 @@ def test_pil_no_tkinter(pyi_builder): # The tkinter module may be available for import, but not actually importable due to missing shared libraries. # Therefore, we need to use `can_import_module`-based skip decorator instead of `@importorskip`. -@importorskip('PIL') @pytest.mark.skipif(not can_import_module("tkinter"), reason="tkinter cannot be imported.") def test_pil_tkinter(pyi_builder): """ @@ -83,7 +143,6 @@ def test_pil_tkinter(pyi_builder): ) -@importorskip('PIL') @importorskip('matplotlib') def test_pil_no_matplotlib(pyi_builder): """ diff --git a/tests/functional/test_pkg_resources.py b/tests/functional/test_pkg_resources.py index f706640046..37d5e259ae 100644 --- a/tests/functional/test_pkg_resources.py +++ b/tests/functional/test_pkg_resources.py @@ -32,6 +32,27 @@ def test_pkg_resources_importable(pyi_builder): """) +def test_pkg_resources_resource_string(pyi_builder): + add_data_arg = f"{_MODULES_DIR / 'pkg3' / 'sample-data.txt'}:pkg3" + pyi_builder.test_source( + """ + import pkg_resources + import pkg3 + + expected_data = b'This is data text for testing the packaging module data.' + + # In a frozen app, the resources is available at: os.path.join(sys._MEIPASS, 'pkg3/sample-data.txt') + data = pkg_resources.resource_string(pkg3.__name__, 'sample-data.txt') + if not data: + raise SystemExit('Error: Could not read data with pkg_resources.resource_string().') + + if data.strip() != expected_data: + raise SystemExit('Error: Read data does not match expected data!') + """, + pyi_args=['--add-data', add_data_arg], + ) + + # Tests for pkg_resources provider. # # These tests run a test script (scripts/pyi_pkg_resources_provider.py) in unfrozen and frozen form, in combination with diff --git a/tests/functional/test_pkgutil.py b/tests/functional/test_pkgutil.py index 66d8483557..43b3c86abb 100644 --- a/tests/functional/test_pkgutil.py +++ b/tests/functional/test_pkgutil.py @@ -8,7 +8,61 @@ # # SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception) #----------------------------------------------------------------------------- -# + +import os +import pathlib + +import pytest + +from PyInstaller.compat import exec_python_rc +from PyInstaller.utils.tests import importable, xfail, onedir_only, onefile_only + +# Directory with testing modules used in some tests. +_MODULES_DIR = pathlib.Path(__file__).parent / 'modules' + + +# Tests for pkgutil.get_data(). +def test_pkgutil_get_data(pyi_builder): + add_data_arg = f"{_MODULES_DIR / 'pkg3' / 'sample-data.txt'}:pkg3" + pyi_builder.test_source( + """ + import pkgutil + import pkg3 # Serves as a hiddenimport + + expected_data = b'This is data text for testing the packaging module data.' + + data = pkgutil.get_data('pkg3', 'sample-data.txt') + print("Read data: {data!r}") + if not data: + raise SystemExit('Error: Could not read data with pkgutil.get_data().') + + if data.strip() != expected_data: + raise SystemExit('Error: Read data does not match expected data!') + """, + pyi_args=['--add-data', add_data_arg], + ) + + +@xfail(reason='Our import mechanism returns the wrong loader-class for __main__.') +def test_pkgutil_get_data__main__(pyi_builder): + add_data_arg = f"{_MODULES_DIR / 'pkg3' / 'sample-data.txt'}:pkg3" + pyi_builder.test_source( + """ + import pkgutil + + expected_data = b'This is data text for testing the packaging module data.' + + data = pkgutil.get_data('__main__', 'pkg3/sample-data.txt') + if not data: + raise SystemExit('Error: Could not read data with pkgutil.get_data().') + + if data.strip() != expected_data: + raise SystemExit('Error: Read data does not match expected data!') + """, + pyi_args=['--add-data', add_data_arg], + ) + + # Tests for pkgutil.iter_modules(). The test attempts to list contents of a package in both unfrozen and frozen version, # and compares the obtained lists. # @@ -21,17 +75,6 @@ # they are again handled directly by python's FileFinder. Therefore, each test is performed both in archive and in # noarchive mode, to cover both cases. -import os -import pathlib - -import pytest - -from PyInstaller.compat import exec_python_rc -from PyInstaller.utils.tests import importable, onedir_only, onefile_only - -# Directory with testing modules used in some tests. -_MODULES_DIR = pathlib.Path(__file__).parent / 'modules' - # Read the output file produced by test script. Each line consists of two elements separated by semi-colon: # name;ispackage