1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#-----------------------------------------------------------------------------
# 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 os
import sys
import pathlib
import pytest
from PyInstaller.building import utils
def test_format_binaries_and_datas_not_found_raises_error(tmp_path):
datas = [('non-existing.txt', '.')]
(tmp_path / 'existing.txt').touch() # Create a file with different name, for sanity check.
# TODO Tighten test when introducing PyInstaller.exceptions
with pytest.raises(SystemExit):
utils.format_binaries_and_datas(datas, str(tmp_path))
def test_format_binaries_and_datas_empty_src(tmp_path):
# `format_binaries_and_datas()` must disallow empty src in `binaries`/`datas` tuples, as those result in implicit
# collection of the whole current working directory .
datas = [('', '.')]
with pytest.raises(SystemExit, match="Empty SRC is not allowed"):
utils.format_binaries_and_datas(datas, str(tmp_path))
def test_format_binaries_and_datas_basic(tmp_path):
# (src, dest) tuples to be passed to format_binaries_and_datas()
DATAS = (
('existing.txt', '.'),
('other.txt', 'foo'),
('*.log', 'logs'),
('a/*.log', 'lll'),
('a/here.tex', '.'),
('b/[abc].tex', 'tex'),
)
# Expected entries; they are listed as (src, dest) tuples for readability; the subsequent code transforms them into
# (dest, src) tuples format used by format_binaries_and_datas().
EXPECTED = (
('existing.txt', 'existing.txt'),
('other.txt', 'foo/other.txt'),
('aaa.log', 'logs/aaa.log'),
('bbb.log', 'logs/bbb.log'),
('a/xxx.log', 'lll/xxx.log'),
('a/yyy.log', 'lll/yyy.log'),
('a/here.tex', 'here.tex'),
('b/a.tex', 'tex/a.tex'),
('b/b.tex', 'tex/b.tex'),
)
# Normalize separator in source paths
datas = [(os.path.normpath(src), dest) for src, dest in DATAS]
# Convert the (src, dest) entries from EXPECTED into (dest, src) format, and turn `src` into full path.
expected = set()
for src, dest in EXPECTED:
src_path = tmp_path / src
dest_path = pathlib.PurePath(dest) # Normalize separators.
# Create the file
src_path.parent.mkdir(parents=True, exist_ok=True)
src_path.touch()
# Expected entry
expected.add((str(dest_path), str(src_path)))
# Create some additional files that should not be included.
(tmp_path / 'not.txt').touch()
(tmp_path / 'a' / 'not.txt').touch()
(tmp_path / 'b' / 'not.txt').touch()
res = utils.format_binaries_and_datas(datas, str(tmp_path))
assert res == expected
def test_format_binaries_and_datas_with_bracket(tmp_path):
# See issue #2314: the filename contains brackets which are interpreted by glob().
DATAS = (
(('b/[abc].tex'), 'tex'),
) # yapf: disable
EXPECTED = (
('b/[abc].tex', 'tex/[abc].tex'),
) # yapf: disable
# Normalize separator in source paths
datas = [(os.path.normpath(src), dest) for src, dest in DATAS]
# Convert the (src, dest) entries from EXPECTED into (dest, src) format, and turn `src` into full path.
expected = set()
for src, dest in EXPECTED:
src_path = tmp_path / src
dest_path = pathlib.PurePath(dest) # Normalize separators.
# Create the file
src_path.parent.mkdir(parents=True, exist_ok=True)
src_path.touch()
# Expected entry
expected.add((str(dest_path), str(src_path)))
# Create some additional files that should not be included.
(tmp_path / 'tex').mkdir(parents=True, exist_ok=True)
(tmp_path / 'tex' / 'not.txt').touch()
res = utils.format_binaries_and_datas(datas, str(tmp_path))
assert res == expected
def test_should_include_system_binary():
python_dir = f'python{sys.version_info.major}.{sys.version_info.minor}'
CASES = [
(f'{python_dir}/lib-dynload/any', f'/usr/lib64/{python_dir}/lib-dynload/any', [], True),
('libany', '/lib64/libpython.so', [], True),
('any', '/lib/python/site-packages/any', [], True),
('libany', '/etc/libany', [], True),
('libany', '/usr/lib/libany', ['*any*'], True),
('libany2', '/lib/libany2', ['libnone*', 'libany*'], True),
('libnomatch', '/lib/libnomatch', ['libnone*', 'libany*'], False),
]
for case in CASES:
tuple = (case[0], case[1])
excepts = case[2]
expected = case[3]
assert utils._should_include_system_binary(tuple, excepts) == expected
|