|
|
"""Tests for distutils.spawn.""" |
|
|
|
|
|
import os |
|
|
import stat |
|
|
import sys |
|
|
import unittest.mock as mock |
|
|
from distutils.errors import DistutilsExecError |
|
|
from distutils.spawn import find_executable, spawn |
|
|
from distutils.tests import support |
|
|
|
|
|
import path |
|
|
import pytest |
|
|
from test.support import unix_shell |
|
|
|
|
|
from .compat import py39 as os_helper |
|
|
|
|
|
|
|
|
class TestSpawn(support.TempdirManager): |
|
|
@pytest.mark.skipif("os.name not in ('nt', 'posix')") |
|
|
def test_spawn(self): |
|
|
tmpdir = self.mkdtemp() |
|
|
|
|
|
|
|
|
|
|
|
if sys.platform != 'win32': |
|
|
exe = os.path.join(tmpdir, 'foo.sh') |
|
|
self.write_file(exe, f'#!{unix_shell}\nexit 1') |
|
|
else: |
|
|
exe = os.path.join(tmpdir, 'foo.bat') |
|
|
self.write_file(exe, 'exit 1') |
|
|
|
|
|
os.chmod(exe, 0o777) |
|
|
with pytest.raises(DistutilsExecError): |
|
|
spawn([exe]) |
|
|
|
|
|
|
|
|
if sys.platform != 'win32': |
|
|
exe = os.path.join(tmpdir, 'foo.sh') |
|
|
self.write_file(exe, f'#!{unix_shell}\nexit 0') |
|
|
else: |
|
|
exe = os.path.join(tmpdir, 'foo.bat') |
|
|
self.write_file(exe, 'exit 0') |
|
|
|
|
|
os.chmod(exe, 0o777) |
|
|
spawn([exe]) |
|
|
|
|
|
def test_find_executable(self, tmp_path): |
|
|
program_path = self._make_executable(tmp_path, '.exe') |
|
|
program = program_path.name |
|
|
program_noeext = program_path.with_suffix('').name |
|
|
filename = str(program_path) |
|
|
tmp_dir = path.Path(tmp_path) |
|
|
|
|
|
|
|
|
rv = find_executable(program, path=tmp_dir) |
|
|
assert rv == filename |
|
|
|
|
|
if sys.platform == 'win32': |
|
|
|
|
|
rv = find_executable(program_noeext, path=tmp_dir) |
|
|
assert rv == filename |
|
|
|
|
|
|
|
|
with tmp_dir: |
|
|
rv = find_executable(program) |
|
|
assert rv == program |
|
|
|
|
|
|
|
|
dont_exist_program = "dontexist_" + program |
|
|
rv = find_executable(dont_exist_program, path=tmp_dir) |
|
|
assert rv is None |
|
|
|
|
|
|
|
|
with os_helper.EnvironmentVarGuard() as env: |
|
|
env['PATH'] = '' |
|
|
with ( |
|
|
mock.patch( |
|
|
'distutils.spawn.os.confstr', return_value=tmp_dir, create=True |
|
|
), |
|
|
mock.patch('distutils.spawn.os.defpath', tmp_dir), |
|
|
): |
|
|
rv = find_executable(program) |
|
|
assert rv is None |
|
|
|
|
|
|
|
|
with tmp_dir: |
|
|
rv = find_executable(program) |
|
|
assert rv == program |
|
|
|
|
|
|
|
|
with os_helper.EnvironmentVarGuard() as env: |
|
|
env['PATH'] = os.pathsep |
|
|
with ( |
|
|
mock.patch('distutils.spawn.os.confstr', return_value='', create=True), |
|
|
mock.patch('distutils.spawn.os.defpath', ''), |
|
|
): |
|
|
rv = find_executable(program) |
|
|
assert rv is None |
|
|
|
|
|
|
|
|
with tmp_dir: |
|
|
rv = find_executable(program) |
|
|
assert rv == program |
|
|
|
|
|
|
|
|
with os_helper.EnvironmentVarGuard() as env: |
|
|
env.pop('PATH', None) |
|
|
|
|
|
|
|
|
with ( |
|
|
mock.patch( |
|
|
'distutils.spawn.os.confstr', side_effect=ValueError, create=True |
|
|
), |
|
|
mock.patch('distutils.spawn.os.defpath', tmp_dir), |
|
|
): |
|
|
rv = find_executable(program) |
|
|
assert rv == filename |
|
|
|
|
|
|
|
|
with ( |
|
|
mock.patch( |
|
|
'distutils.spawn.os.confstr', return_value=tmp_dir, create=True |
|
|
), |
|
|
mock.patch('distutils.spawn.os.defpath', ''), |
|
|
): |
|
|
rv = find_executable(program) |
|
|
assert rv == filename |
|
|
|
|
|
@staticmethod |
|
|
def _make_executable(tmp_path, ext): |
|
|
|
|
|
|
|
|
program = tmp_path.joinpath('program').with_suffix(ext) |
|
|
program.write_text("", encoding='utf-8') |
|
|
program.chmod(stat.S_IXUSR) |
|
|
return program |
|
|
|
|
|
def test_spawn_missing_exe(self): |
|
|
with pytest.raises(DistutilsExecError) as ctx: |
|
|
spawn(['does-not-exist']) |
|
|
assert "command 'does-not-exist' failed" in str(ctx.value) |
|
|
|