/
niceSOFT
/
python3-build
Обзор
Документация
Войти
/
niceSOFT
/
python3-build
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
1.5.0
tests/test_main.py
883 строки
30 KB
Henry Schreiner
fix: api should not ignore installed, only CLI (#1056)
29 апр 2026, 23:54
Не верифицирован
29 апр 2026, 23:54
776f702
Код
Авторство
О чём код?
# SPDX-License-Identifier: MIT from __future__ import annotations import contextlib import io import json import os import pathlib import re import subprocess import sys import unittest.mock import venv from typing import Any import pytest import pytest_mock import build import build.__main__ pytestmark = pytest.mark.contextvars build_open_owner = 'builtins' cwd = os.getcwd() out = os.path.join(cwd, 'dist') ANSI_STRIP = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') @pytest.mark.parametrize( ('cli_args', 'build_args', 'build_kwargs', 'hook'), [ ( [], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['-n'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': False, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['-s'], (cwd, out), { 'distributions': ['sdist'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package', ), ( ['-w'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package', ), ( ['-s', '-w'], (cwd, out), { 'distributions': ['sdist', 'wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package', ), ( ['source'], ('source', os.path.join('source', 'dist')), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['-o', 'out'], (cwd, 'out'), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['source', '-o', 'out'], ('source', 'out'), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['-x'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': True, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['--installer', 'uv'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': 'uv', }, 'build_package_via_sdist', ), ( ['-C--flag1', '-C--flag2'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {'--flag1': '', '--flag2': ''}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['-C--flag=value'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {'--flag': 'value'}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['-C--flag1=value', '-C--flag2=other_value', '-C--flag2=extra_value'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {'--flag1': 'value', '--flag2': ['other_value', 'extra_value']}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['--config-json={"one": 1, "two": [2, 3], "three": {"in": "out"}}'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {'one': 1, 'two': [2, 3], 'three': {'in': 'out'}}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['--config-json', '{"outer": {"inner": {"deeper": 2}}}'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {'outer': {'inner': {'deeper': 2}}}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['--config-json', '{}'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': None, 'installer': None, }, 'build_package_via_sdist', ), ( ['--dependency-constraints-txt', 'contraints.txt'], (cwd, out), { 'distributions': ['wheel'], 'config_settings': {}, 'isolation': True, 'skip_dependency_check': False, 'dependency_constraints_txt': 'contraints.txt', 'installer': None, }, 'build_package_via_sdist', ), ], ) def test_parse_args( mocker: pytest_mock.MockerFixture, cli_args: list[str], build_args: tuple[Any, Any], build_kwargs: dict[str, Any], hook: str, ) -> None: build_package = mocker.patch('build.__main__.build_package', return_value=['something']) build_package_via_sdist = mocker.patch('build.__main__.build_package_via_sdist', return_value=['something']) build.__main__.main(cli_args) if hook == 'build_package': build_package.assert_called_with(*build_args, **build_kwargs) elif hook == 'build_package_via_sdist': build_package_via_sdist.assert_called_with(*build_args, **build_kwargs) else: # pragma: no cover msg = f'Unknown hook {hook}' raise ValueError(msg) def test_prog() -> None: out = io.StringIO() with pytest.raises(SystemExit), contextlib.redirect_stdout(out): build.__main__.main(['--help'], prog='something') assert out.getvalue().startswith('usage: something [-h]') def test_version(capsys: pytest.CaptureFixture[str]) -> None: with pytest.raises(SystemExit): build.__main__.main(['--version']) out, _ = capsys.readouterr() assert out.startswith(f'build {build.__version__}') @pytest.mark.isolated def test_build_isolated(mocker: pytest_mock.MockerFixture, package_test_flit: str) -> None: build_cmd = mocker.patch('build.ProjectBuilder.build', return_value='something') required_cmd = mocker.patch( 'build.ProjectBuilder.get_requires_for_build', side_effect=[ ['dep1', 'dep2'], ], ) mocker.patch('build.__main__._error') install = mocker.patch('build.env.DefaultIsolatedEnv.install') build.__main__.build_package(package_test_flit, '.', ['sdist']) install.assert_any_call({'flit_core >=2,<4'}, _fresh=True) required_cmd.assert_called_with('sdist', None) install.assert_any_call(['dep1', 'dep2']) build_cmd.assert_called_with('sdist', '.', None) def test_build_no_isolation_check_deps_empty(mocker: pytest_mock.MockerFixture, package_test_flit: str) -> None: # check_dependencies = [] build_cmd = mocker.patch('build.ProjectBuilder.build', return_value='something') mocker.patch('build.ProjectBuilder.check_dependencies', return_value=[]) build.__main__.build_package(package_test_flit, '.', ['sdist'], isolation=False) build_cmd.assert_called_with('sdist', '.', None) def test_build_package_passes_config_settings_to_build(mocker: pytest_mock.MockerFixture, package_test_flit: str) -> None: build_cmd = mocker.patch( 'build.__main__._build', side_effect=[ os.path.join('dist', 'test_flit-1.0.0.tar.gz'), os.path.join('dist', 'test_flit-1.0.0-py3-none-any.whl'), ], ) config_settings = {'--flag': 'value'} built = build.__main__.build_package( package_test_flit, '.', ['sdist', 'wheel'], config_settings=config_settings, isolation=False, skip_dependency_check=True, dependency_constraints_txt=pathlib.Path('constraints.txt'), installer='uv', ) assert built == ['test_flit-1.0.0.tar.gz', 'test_flit-1.0.0-py3-none-any.whl'] build_cmd.assert_has_calls( [ unittest.mock.call( False, package_test_flit, '.', 'sdist', config_settings, True, pathlib.Path('constraints.txt'), 'uv' ), unittest.mock.call( False, package_test_flit, '.', 'wheel', config_settings, True, pathlib.Path('constraints.txt'), 'uv' ), ] ) def test_build_package_via_sdist_passes_config_settings_to_build(mocker: pytest_mock.MockerFixture) -> None: build_cmd = mocker.patch( 'build.__main__._build', side_effect=[ os.path.join('dist', 'demo-1.0.0.tar.gz'), os.path.join('dist', 'demo-1.0.0-py3-none-any.whl'), ], ) mocker.patch('build.__main__.tempfile.mkdtemp', return_value='temp-sdist-dir') mocker.patch('build.__main__.shutil.rmtree') tar_open = mocker.patch('build._compat.tarfile.TarFile.open') mocker.patch('build.__main__._ctx.log') config_settings = {'--flag': 'value'} built = build.__main__.build_package_via_sdist( 'src', 'dist', ['wheel'], config_settings=config_settings, isolation=False, skip_dependency_check=True, dependency_constraints_txt=pathlib.Path('constraints.txt'), installer='uv', ) assert built == ['demo-1.0.0.tar.gz', 'demo-1.0.0-py3-none-any.whl'] tar_open.return_value.__enter__.return_value.extractall.assert_called_once_with('temp-sdist-dir') build_cmd.assert_has_calls( [ unittest.mock.call(False, 'src', 'dist', 'sdist', config_settings, True, pathlib.Path('constraints.txt'), 'uv'), unittest.mock.call( False, os.path.join('temp-sdist-dir', 'demo-1.0.0'), 'dist', 'wheel', config_settings, True, pathlib.Path('constraints.txt'), 'uv', ), ] ) build.__main__.shutil.rmtree.assert_called_once_with('temp-sdist-dir', ignore_errors=True) # type: ignore[attr-defined] @pytest.mark.parametrize( ('missing_deps', 'output'), [ ([('foo',)], '\n\tfoo'), ([('foo',), ('bar', 'baz', 'qux')], '\n\tfoo\n\tbar -> baz -> qux'), ], ) def test_build_no_isolation_with_check_deps( mocker: pytest_mock.MockerFixture, package_test_flit: str, missing_deps: list[tuple[str, ...]], output: str ) -> None: error = mocker.patch('build.__main__._error') build_cmd = mocker.patch('build.ProjectBuilder.build', return_value='something') mocker.patch('build.ProjectBuilder.check_dependencies', return_value=missing_deps) build.__main__.build_package(package_test_flit, '.', ['sdist'], isolation=False) build_cmd.assert_called_with('sdist', '.', None) error.assert_called_with('Missing dependencies:' + output) @pytest.mark.parametrize( ('cli_args', 'err_msg'), [ (['-Cone=1', '--config-json={"two": 2}'], 'not allowed with argument'), (['--config-json={"two": 2'], 'Invalid JSON in --config-json'), (['--config-json=[1]'], '--config-json must contain a JSON object'), ], ) def test_config_json_errors(cli_args: list[str], err_msg: str, capsys: pytest.CaptureFixture[str]) -> None: with pytest.raises(SystemExit): build.__main__.main(cli_args) outerr = capsys.readouterr() assert err_msg in outerr.out or err_msg in outerr.err @pytest.mark.isolated def test_build_raises_build_exception(mocker: pytest_mock.MockerFixture, package_test_flit: str) -> None: mocker.patch('build.ProjectBuilder.get_requires_for_build', side_effect=build.BuildException) mocker.patch('build.env.DefaultIsolatedEnv.install') with pytest.raises(build.BuildException): build.__main__.build_package(package_test_flit, '.', ['sdist']) @pytest.mark.isolated def test_build_raises_build_backend_exception(mocker: pytest_mock.MockerFixture, package_test_flit: str) -> None: mocker.patch('build.ProjectBuilder.get_requires_for_build', side_effect=build.BuildBackendException(Exception('a'))) mocker.patch('build.env.DefaultIsolatedEnv.install') msg = f"Backend operation failed: Exception('a'{',' if sys.version_info < (3, 7) else ''})" with pytest.raises(build.BuildBackendException, match=re.escape(msg)): build.__main__.build_package(package_test_flit, '.', ['sdist']) @pytest.mark.network @pytest.mark.pypy3323bug def test_build_package(tmp_dir: str, package_test_setuptools: str) -> None: build.__main__.build_package(package_test_setuptools, tmp_dir, ['sdist', 'wheel']) assert sorted(os.listdir(tmp_dir)) == [ 'test_setuptools-1.0.0-py3-none-any.whl', 'test_setuptools-1.0.0.tar.gz', ] @pytest.mark.network @pytest.mark.pypy3323bug def test_build_package_via_sdist(tmp_dir: str, package_test_setuptools: str) -> None: build.__main__.build_package_via_sdist(package_test_setuptools, tmp_dir, ['wheel']) assert sorted(os.listdir(tmp_dir)) == [ 'test_setuptools-1.0.0-py3-none-any.whl', 'test_setuptools-1.0.0.tar.gz', ] @pytest.mark.pypy3323bug def test_build_package_via_sdist_incomplete_sdist(tmp_dir: str, package_test_cant_build_via_sdist: str) -> None: with pytest.raises(build.BuildBackendException): build.__main__.build_package_via_sdist(package_test_cant_build_via_sdist, tmp_dir, ['wheel']) def test_build_package_via_sdist_invalid_distribution(tmp_dir: str, package_test_setuptools: str) -> None: with pytest.raises(ValueError, match='Only binary distributions are allowed but sdist was specified'): build.__main__.build_package_via_sdist(package_test_setuptools, tmp_dir, ['sdist']) @pytest.mark.isolated def test_build_package_with_constraints( mocker: pytest_mock.MockerFixture, tmp_path: pathlib.Path, package_test_flit: str ) -> None: install = mocker.patch('build.env.DefaultIsolatedEnv.install') constraints_txt_path = tmp_path.joinpath('constraints.txt') constraints_txt_path.write_text( """\ flit-core==12.34 foo==wot """, encoding='utf-8', ) with pytest.raises(build.BuildBackendException, match=re.escape("Backend 'flit_core.buildapi' is not available.")): build.__main__.build_package(package_test_flit, tmp_path, ['wheel'], dependency_constraints_txt=constraints_txt_path) install.assert_any_call({'flit_core >=2,<4'}, constraints={'flit-core==12.34', 'foo==wot'}, _fresh=True) @pytest.mark.pypy3323bug @pytest.mark.parametrize( ('args', 'output'), [ pytest.param( [], [ '* Creating isolated environment: venv+pip...', '* Installing packages in isolated environment:', ' - setuptools >= 42.0.0', '* Getting build dependencies for sdist...', '* Building sdist...', '* Building wheel from sdist', '* Creating isolated environment: venv+pip...', '* Installing packages in isolated environment:', ' - setuptools >= 42.0.0', '* Getting build dependencies for wheel...', '* Building wheel...', 'Successfully built test_setuptools-1.0.0.tar.gz and test_setuptools-1.0.0-py3-none-any.whl', ], id='via-sdist-isolation', marks=[pytest.mark.network, pytest.mark.isolated], ), pytest.param( ['--no-isolation'], [ '* Getting build dependencies for sdist...', '* Building sdist...', '* Building wheel from sdist', '* Getting build dependencies for wheel...', '* Building wheel...', 'Successfully built test_setuptools-1.0.0.tar.gz and test_setuptools-1.0.0-py3-none-any.whl', ], id='via-sdist-no-isolation', ), pytest.param( ['--wheel'], [ '* Creating isolated environment: venv+pip...', '* Installing packages in isolated environment:', ' - setuptools >= 42.0.0', '* Getting build dependencies for wheel...', '* Building wheel...', 'Successfully built test_setuptools-1.0.0-py3-none-any.whl', ], id='wheel-direct-isolation', marks=[pytest.mark.network, pytest.mark.isolated], ), pytest.param( ['--wheel', '--no-isolation'], [ '* Getting build dependencies for wheel...', '* Building wheel...', 'Successfully built test_setuptools-1.0.0-py3-none-any.whl', ], id='wheel-direct-no-isolation', ), pytest.param( ['--sdist', '--no-isolation'], [ '* Getting build dependencies for sdist...', '* Building sdist...', 'Successfully built test_setuptools-1.0.0.tar.gz', ], id='sdist-direct-no-isolation', ), pytest.param( ['--sdist', '--wheel', '--no-isolation'], [ '* Getting build dependencies for sdist...', '* Building sdist...', '* Getting build dependencies for wheel...', '* Building wheel...', 'Successfully built test_setuptools-1.0.0.tar.gz and test_setuptools-1.0.0-py3-none-any.whl', ], id='sdist-and-wheel-direct-no-isolation', ), pytest.param( ['--metadata'], [ '* Creating isolated environment: venv+pip...', '* Getting metadata for wheel...', '* Getting build dependencies for wheel...', '* Installing packages in isolated environment:', ' - setuptools >= 42.0.0', ], id='metadata-isolation', marks=[pytest.mark.network, pytest.mark.isolated], ), pytest.param( ['--metadata', '--no-isolation'], [ '* Getting build dependencies for wheel...', '* Getting metadata for wheel...', ], id='metadata-no-isolation', ), ], ) @pytest.mark.flaky(reruns=5) def test_logging_output( package_test_setuptools: str, tmp_dir: str, capsys: pytest.CaptureFixture[str], args: list[str], output: list[str] ) -> None: build.__main__.main([package_test_setuptools, '-o', tmp_dir, *args]) _, stderr = capsys.readouterr() assert set(stderr.splitlines()) <= set(output) @pytest.mark.pypy3323bug @pytest.mark.parametrize( ('color', 'stderr_error', 'stderr_body'), [ ( False, 'ERROR ', [ '* Creating isolated environment: venv+pip...', '* Installing packages in isolated environment:', ' - setuptools >= 42.0.0', ' - this is invalid', ], ), ( True, '\33[91mERROR\33[0m ', [ '\33[1m* Creating isolated environment: venv+pip...\33[0m', '\33[1m* Installing packages in isolated environment:\33[0m', ' - setuptools >= 42.0.0', ' - this is invalid', ], ), ], ids=['no-color', 'color'], ) @pytest.mark.usefixtures('local_pip') def test_logging_output_env_subprocess_error( mocker: pytest_mock.MockerFixture, monkeypatch: pytest.MonkeyPatch, package_test_invalid_requirements: str, tmp_dir: str, capsys: pytest.CaptureFixture[str], color: bool, stderr_body: list[str], stderr_error: str, ) -> None: with contextlib.suppress(ModuleNotFoundError): # colorama might not be available # do not inject hook to have clear output on capsys mocker.patch('colorama.init') monkeypatch.delenv('NO_COLOR', raising=False) monkeypatch.setenv('FORCE_COLOR' if color else 'NO_COLOR', '') with pytest.raises(SystemExit): build.__main__.main([package_test_invalid_requirements, '-o', tmp_dir]) outerr = capsys.readouterr() stderr = outerr.err.splitlines() assert stderr[:4] == stderr_body assert stderr[-1].startswith(stderr_error) # Newer versions of pip also color stderr - strip them if present assert any(ANSI_STRIP.sub('', e).strip().startswith('< ERROR: Invalid requirement: ') for e in stderr) @pytest.mark.parametrize( ('tty', 'env', 'colors'), [ (False, {}, build.__main__._NO_COLORS), (True, {}, build.__main__._COLORS), (False, {'NO_COLOR': ''}, build.__main__._NO_COLORS), (True, {'NO_COLOR': ''}, build.__main__._NO_COLORS), (False, {'FORCE_COLOR': ''}, build.__main__._COLORS), (True, {'FORCE_COLOR': ''}, build.__main__._COLORS), ], ) def test_colors( mocker: pytest_mock.MockerFixture, monkeypatch: pytest.MonkeyPatch, tty: bool, env: dict[str, str], colors: dict[str, object], ) -> None: mocker.patch('sys.stdout.isatty', return_value=tty) for key, value in env.items(): monkeypatch.setenv(key, value) build.__main__._init_colors() assert build.__main__._styles.get() == colors def test_colors_conflict(monkeypatch: pytest.MonkeyPatch) -> None: with monkeypatch.context() as m: m.setenv('NO_COLOR', '') m.setenv('FORCE_COLOR', '') with pytest.warns( UserWarning, match='Both NO_COLOR and FORCE_COLOR environment variables are set, disabling color', ): build.__main__._init_colors() assert build.__main__._styles.get() == build.__main__._NO_COLORS def test_logging_output_venv_failure( monkeypatch: pytest.MonkeyPatch, package_test_flit: str, tmp_dir: str, capsys: pytest.CaptureFixture[str] ) -> None: def raise_called_process_err(*_args: object, **_kwargs: object) -> None: raise subprocess.CalledProcessError(1, ['test', 'args'], b'stdoutput', b'stderror') monkeypatch.setattr(venv.EnvBuilder, 'create', raise_called_process_err) monkeypatch.setenv('NO_COLOR', '') with pytest.raises(SystemExit): build.__main__.main([package_test_flit, '-o', tmp_dir]) _, stderr = capsys.readouterr() assert ( stderr == """\ * Creating isolated environment: venv+pip... > test args < stdoutput < stderror ERROR Failed to create venv. Maybe try installing virtualenv. """ ) @pytest.mark.contextvars @pytest.mark.network def test_verbose_logging_output( subtests: Any, capfd: pytest.CaptureFixture[str], monkeypatch: pytest.MonkeyPatch, tmp_dir: str, package_test_setuptools: str, ) -> None: monkeypatch.setenv('NO_COLOR', '') no_of_lines = -1 for verbosity in range(-2, 3): with subtests.test(verbosity=verbosity): cmd = [package_test_setuptools, '-w', '-o', tmp_dir] if verbosity: cmd.insert(0, f'-{("v" if verbosity > 0 else "q") * abs(verbosity)}') build.__main__.main(cmd) new_no_of_lines = sum(1 for s in capfd.readouterr() for i in s.splitlines()) assert new_no_of_lines > no_of_lines no_of_lines = new_no_of_lines def test_metadata_json_output( capsys: pytest.CaptureFixture[str], package_test_setuptools: str, ) -> None: build.__main__.main([package_test_setuptools, '--metadata', '-n']) stdout = capsys.readouterr().out metadata = json.loads(stdout) # Name normalised in old versions of setuptools. assert metadata['name'] in {'test_setuptools', 'test-setuptools'} assert metadata['version'] == '1.0.0' def test_setup_cli_windows_colorama_available(mocker: pytest_mock.MockerFixture) -> None: mocker.patch('platform.system', return_value='Windows') colorama = mocker.MagicMock() mocker.patch.dict('sys.modules', {'colorama': colorama}) build.__main__._setup_cli(verbosity=0) colorama.init.assert_called_once() def test_setup_cli_windows_colorama_missing(mocker: pytest_mock.MockerFixture) -> None: mocker.patch('platform.system', return_value='Windows') mocker.patch.dict('sys.modules', {'colorama': None}) build.__main__._setup_cli(verbosity=0) def test_setup_cli_non_windows(mocker: pytest_mock.MockerFixture) -> None: mocker.patch('platform.system', return_value='Linux') build.__main__._setup_cli(verbosity=0) def test_metadata_with_distributions_error() -> None: with pytest.raises(SystemExit): build.__main__.main(['--metadata', '--sdist']) def test_entrypoint(mocker: pytest_mock.MockerFixture) -> None: main = mocker.patch('build.__main__.main') build.__main__.entrypoint() main.assert_called_once_with(sys.argv[1:]) def test_handle_build_error_build_backend_exception(mocker: pytest_mock.MockerFixture) -> None: mocker.patch('build.__main__._error', side_effect=SystemExit(1)) exc = ValueError('test error') try: raise exc except ValueError: exc_info = sys.exc_info() with pytest.raises(SystemExit), build.__main__._handle_build_error(): raise build.BuildBackendException(exc, exc_info=exc_info) def test_log_unknown_kind(mocker: pytest_mock.MockerFixture) -> None: mocker.patch('build.__main__._cprint') log = build.__main__._make_logger() log('message', kind=('unknown',)) def test_build_no_isolation_skip_dependency_check(mocker: pytest_mock.MockerFixture, package_test_flit: str) -> None: build_cmd = mocker.patch('build.ProjectBuilder.build', return_value='something') build.__main__.build_package(package_test_flit, '.', ['sdist'], isolation=False, skip_dependency_check=True) build_cmd.assert_called_with('sdist', '.', None) def test_build_package_via_sdist_empty_distributions(mocker: pytest_mock.MockerFixture) -> None: mocker.patch( 'build.__main__._build', return_value=os.path.join('dist', 'demo-1.0.0.tar.gz'), ) result = build.__main__.build_package_via_sdist('src', 'dist', []) assert result == ['demo-1.0.0.tar.gz'] def test_parse_config_settings_triple_duplicate() -> None: result = build.__main__._parse_config_settings(['--flag=a', '--flag=b', '--flag=c']) assert result == {'--flag': ['a', 'b', 'c']} def test_build_metadata_runner_without_extra_environ( mocker: pytest_mock.MockerFixture, tmp_path: pathlib.Path, package_test_setuptools: str, ) -> None: captured_runners: list[Any] = [] @contextlib.contextmanager def fake_bootstrap(*_args: object, **kwargs: object) -> Any: captured_runners.append(kwargs['runner']) builder = mocker.MagicMock() metadata_dir = tmp_path / 'metadata' metadata_dir.mkdir() (metadata_dir / 'METADATA').write_bytes(b'Metadata-Version: 2.2\nName: test\nVersion: 1.0\n') builder.metadata_path.return_value = str(metadata_dir) yield builder mocker.patch('build.__main__._bootstrap_build_env', side_effect=fake_bootstrap) ctx_run = mocker.patch('build.__main__._ctx.run_subprocess') build.__main__._build_metadata(package_test_setuptools, '.', ['wheel'], isolation=False, skip_dependency_check=True) assert captured_runners captured_runners[0](['echo', 'test']) ctx_run.assert_called_once_with(['echo', 'test'], None, mocker.ANY)