diff --git a/setuptools/_distutils/dist.py b/setuptools/_distutils/dist.py index 1dc25fe541..917cd94a0c 100644 --- a/setuptools/_distutils/dist.py +++ b/setuptools/_distutils/dist.py @@ -334,7 +334,7 @@ def find_config_files(self): - a file named by an environment variable """ check_environ() - files = [str(path) for path in self._gen_paths() if path.is_file()] + files = [str(path) for path in self._gen_paths() if os.path.isfile(path)] if DEBUG: self.announce("using config files: %s" % ', '.join(files)) diff --git a/setuptools/_distutils/sysconfig.py b/setuptools/_distutils/sysconfig.py index 3dd8185f79..6a979f8c91 100644 --- a/setuptools/_distutils/sysconfig.py +++ b/setuptools/_distutils/sysconfig.py @@ -13,6 +13,7 @@ import re import sys import sysconfig +import pathlib from .errors import DistutilsPlatformError from . import py39compat @@ -40,14 +41,13 @@ project_base = os.getcwd() -# python_build: (Boolean) if true, we're either building Python or -# building an extension with an un-installed Python, so we use -# different (hard-wired) directories. def _is_python_source_dir(d): - for fn in ("Setup", "Setup.local"): - if os.path.isfile(os.path.join(d, "Modules", fn)): - return True - return False + """ + Return True if the target directory appears to point to an + un-installed Python. + """ + modules = pathlib.Path(d).joinpath('Modules') + return any(modules.joinpath(fn).is_file() for fn in ('Setup', 'Setup.local')) _sys_home = getattr(sys, '_home', None) diff --git a/setuptools/_distutils/tests/py37compat.py b/setuptools/_distutils/tests/py37compat.py new file mode 100644 index 0000000000..e5d406a3b6 --- /dev/null +++ b/setuptools/_distutils/tests/py37compat.py @@ -0,0 +1,18 @@ +import os +import sys +import platform + + +def subprocess_args_compat(*args): + return list(map(os.fspath, args)) + + +def subprocess_args_passthrough(*args): + return list(args) + + +subprocess_args = ( + subprocess_args_compat + if platform.system() == "Windows" and sys.version_info < (3, 8) + else subprocess_args_passthrough +) diff --git a/setuptools/_distutils/tests/py38compat.py b/setuptools/_distutils/tests/py38compat.py index 35ddbb5bde..211d3a6c50 100644 --- a/setuptools/_distutils/tests/py38compat.py +++ b/setuptools/_distutils/tests/py38compat.py @@ -18,27 +18,19 @@ try: from test.support.os_helper import ( - change_cwd, rmtree, EnvironmentVarGuard, - TESTFN, unlink, skip_unless_symlink, temp_dir, - create_empty_file, - temp_cwd, ) except (ModuleNotFoundError, ImportError): from test.support import ( - change_cwd, rmtree, EnvironmentVarGuard, - TESTFN, unlink, skip_unless_symlink, temp_dir, - create_empty_file, - temp_cwd, ) diff --git a/setuptools/_distutils/tests/test_archive_util.py b/setuptools/_distutils/tests/test_archive_util.py index 72aa9d7c7b..d0f5b73481 100644 --- a/setuptools/_distutils/tests/test_archive_util.py +++ b/setuptools/_distutils/tests/test_archive_util.py @@ -9,6 +9,7 @@ import pathlib import pytest +import path from distutils import archive_util from distutils.archive_util import ( @@ -23,7 +24,6 @@ from test.support import patch from .unix_compat import require_unix_id, require_uid_0, grp, pwd, UID_0_SUPPORT -from .py38compat import change_cwd from .py38compat import check_warnings @@ -95,7 +95,7 @@ def _make_tarball(self, tmpdir, target_name, suffix, **kwargs): base_name = os.path.join(tmpdir2, target_name) # working with relative paths to avoid tar warnings - with change_cwd(tmpdir): + with path.Path(tmpdir): make_tarball(splitdrive(base_name)[1], 'dist', **kwargs) # check if the compressed tarball was created @@ -227,7 +227,7 @@ def test_make_zipfile(self): # creating something to tar tmpdir = self._create_files() base_name = os.path.join(self.mkdtemp(), 'archive') - with change_cwd(tmpdir): + with path.Path(tmpdir): make_zipfile(base_name, 'dist') # check if the compressed tarball was created @@ -253,7 +253,7 @@ def fake_zipfile(*a, **kw): # create something to tar and compress tmpdir = self._create_files() base_name = os.path.join(self.mkdtemp(), 'archive') - with change_cwd(tmpdir): + with path.Path(tmpdir): make_zipfile(base_name, 'dist') tarball = base_name + '.zip' diff --git a/setuptools/_distutils/tests/test_build_ext.py b/setuptools/_distutils/tests/test_build_ext.py index e60814ff64..cf6e98985c 100644 --- a/setuptools/_distutils/tests/test_build_ext.py +++ b/setuptools/_distutils/tests/test_build_ext.py @@ -8,6 +8,10 @@ import tempfile import importlib import shutil +import re + +import path +import pytest from distutils.core import Distribution from distutils.command.build_ext import build_ext @@ -27,10 +31,7 @@ ) from test import support -from . import py38compat as os_helper from . import py38compat as import_helper -import pytest -import re @pytest.fixture() @@ -47,7 +48,7 @@ def user_site_dir(request): # bpo-30132: On Windows, a .pdb file may be created in the current # working directory. Create a temporary working directory to cleanup # everything at the end of the test. - with os_helper.change_cwd(self.tmp_dir): + with path.Path(self.tmp_dir): yield site.USER_BASE = orig_user_base diff --git a/setuptools/_distutils/tests/test_core.py b/setuptools/_distutils/tests/test_core.py index 86b0040f60..5fe7e958f5 100644 --- a/setuptools/_distutils/tests/test_core.py +++ b/setuptools/_distutils/tests/test_core.py @@ -8,7 +8,6 @@ import pytest -from . import py38compat as os_helper from distutils.dist import Distribution # setup script that uses __file__ @@ -61,65 +60,63 @@ def save_stdout(monkeypatch): monkeypatch.setattr(sys, 'stdout', sys.stdout) +@pytest.fixture +def temp_file(tmp_path): + return tmp_path / 'file' + + @pytest.mark.usefixtures('save_env') @pytest.mark.usefixtures('save_argv') -@pytest.mark.usefixtures('cleanup_testfn') class TestCore: - def write_setup(self, text, path=os_helper.TESTFN): - f = open(path, "w") - try: - f.write(text) - finally: - f.close() - return path - - def test_run_setup_provides_file(self): + def test_run_setup_provides_file(self, temp_file): # Make sure the script can use __file__; if that's missing, the test # setup.py script will raise NameError. - distutils.core.run_setup(self.write_setup(setup_using___file__)) + temp_file.write_text(setup_using___file__) + distutils.core.run_setup(temp_file) - def test_run_setup_preserves_sys_argv(self): + def test_run_setup_preserves_sys_argv(self, temp_file): # Make sure run_setup does not clobber sys.argv argv_copy = sys.argv.copy() - distutils.core.run_setup(self.write_setup(setup_does_nothing)) + temp_file.write_text(setup_does_nothing) + distutils.core.run_setup(temp_file) assert sys.argv == argv_copy - def test_run_setup_defines_subclass(self): + def test_run_setup_defines_subclass(self, temp_file): # Make sure the script can use __file__; if that's missing, the test # setup.py script will raise NameError. - dist = distutils.core.run_setup(self.write_setup(setup_defines_subclass)) + temp_file.write_text(setup_defines_subclass) + dist = distutils.core.run_setup(temp_file) install = dist.get_command_obj('install') assert 'cmd' in install.sub_commands - def test_run_setup_uses_current_dir(self): - # This tests that the setup script is run with the current directory - # as its own current directory; this was temporarily broken by a - # previous patch when TESTFN did not use the current directory. + def test_run_setup_uses_current_dir(self, tmp_path): + """ + Test that the setup script is run with the current directory + as its own current directory. + """ sys.stdout = io.StringIO() cwd = os.getcwd() # Create a directory and write the setup.py file there: - os.mkdir(os_helper.TESTFN) - setup_py = os.path.join(os_helper.TESTFN, "setup.py") - distutils.core.run_setup(self.write_setup(setup_prints_cwd, path=setup_py)) + setup_py = tmp_path / 'setup.py' + setup_py.write_text(setup_prints_cwd) + distutils.core.run_setup(setup_py) output = sys.stdout.getvalue() if output.endswith("\n"): output = output[:-1] assert cwd == output - def test_run_setup_within_if_main(self): - dist = distutils.core.run_setup( - self.write_setup(setup_within_if_main), stop_after="config" - ) + def test_run_setup_within_if_main(self, temp_file): + temp_file.write_text(setup_within_if_main) + dist = distutils.core.run_setup(temp_file, stop_after="config") assert isinstance(dist, Distribution) assert dist.get_name() == "setup_within_if_main" - def test_run_commands(self): + def test_run_commands(self, temp_file): sys.argv = ['setup.py', 'build'] - dist = distutils.core.run_setup( - self.write_setup(setup_within_if_main), stop_after="commandline" - ) + temp_file.write_text(setup_within_if_main) + dist = distutils.core.run_setup(temp_file, stop_after="commandline") assert 'build' not in dist.have_run distutils.core.run_commands(dist) assert 'build' in dist.have_run diff --git a/setuptools/_distutils/tests/test_dist.py b/setuptools/_distutils/tests/test_dist.py index a943832620..52e0b3ce26 100644 --- a/setuptools/_distutils/tests/test_dist.py +++ b/setuptools/_distutils/tests/test_dist.py @@ -14,7 +14,6 @@ from distutils.cmd import Command from test.support import captured_stdout, captured_stderr -from .py38compat import TESTFN from distutils.tests import support from distutils import log @@ -95,15 +94,15 @@ def test_command_packages_cmdline(self, clear_argv): 'distutils' not in Distribution.parse_config_files.__module__, reason='Cannot test when virtualenv has monkey-patched Distribution', ) - def test_venv_install_options(self, request): + def test_venv_install_options(self, tmp_path): sys.argv.append("install") - request.addfinalizer(functools.partial(os.unlink, TESTFN)) + file = str(tmp_path / 'file') fakepath = '/somedir' jaraco.path.build( { - TESTFN: f""" + file: f""" [install] install-base = {fakepath} install-platbase = {fakepath} @@ -124,9 +123,9 @@ def test_venv_install_options(self, request): # Base case: Not in a Virtual Environment with mock.patch.multiple(sys, prefix='/a', base_prefix='/a'): - d = self.create_distribution([TESTFN]) + d = self.create_distribution([file]) - option_tuple = (TESTFN, fakepath) + option_tuple = (file, fakepath) result_dict = { 'install_base': option_tuple, @@ -153,35 +152,35 @@ def test_venv_install_options(self, request): # Test case: In a Virtual Environment with mock.patch.multiple(sys, prefix='/a', base_prefix='/b'): - d = self.create_distribution([TESTFN]) + d = self.create_distribution([file]) for key in result_dict.keys(): assert key not in d.command_options.get('install', {}) - def test_command_packages_configfile(self, request, clear_argv): + def test_command_packages_configfile(self, tmp_path, clear_argv): sys.argv.append("build") - request.addfinalizer(functools.partial(os.unlink, TESTFN)) + file = str(tmp_path / "file") jaraco.path.build( { - TESTFN: """ + file: """ [global] command_packages = foo.bar, splat """, } ) - d = self.create_distribution([TESTFN]) + d = self.create_distribution([file]) assert d.get_command_packages() == ["distutils.command", "foo.bar", "splat"] # ensure command line overrides config: sys.argv[1:] = ["--command-packages", "spork", "build"] - d = self.create_distribution([TESTFN]) + d = self.create_distribution([file]) assert d.get_command_packages() == ["distutils.command", "spork"] # Setting --command-packages to '' should cause the default to # be used even if a config file specified something else: sys.argv[1:] = ["--command-packages", "", "build"] - d = self.create_distribution([TESTFN]) + d = self.create_distribution([file]) assert d.get_command_packages() == ["distutils.command"] def test_empty_options(self, request): @@ -259,6 +258,18 @@ def test_find_config_files_disable(self, temp_home): # make sure --no-user-cfg disables the user cfg file assert len(all_files) - 1 == len(files) + @pytest.mark.skipif( + 'platform.system() == "Windows"', + reason='Windows does not honor chmod 000', + ) + def test_find_config_files_permission_error(self, fake_home): + """ + Finding config files should not fail when directory is inaccessible. + """ + fake_home.joinpath(pydistutils_cfg).write_text('') + fake_home.chmod(0o000) + Distribution().find_config_files() + @pytest.mark.usefixtures('save_env') @pytest.mark.usefixtures('save_argv') diff --git a/setuptools/_distutils/tests/test_filelist.py b/setuptools/_distutils/tests/test_filelist.py index 2607182064..7ff9d3e866 100644 --- a/setuptools/_distutils/tests/test_filelist.py +++ b/setuptools/_distutils/tests/test_filelist.py @@ -8,10 +8,12 @@ from distutils import filelist from test.support import captured_stdout -from distutils.tests import support -from . import py38compat as os_helper import pytest +import jaraco.path + +from distutils.tests import support +from . import py38compat as os_helper MANIFEST_IN = """\ @@ -303,44 +305,35 @@ def test_process_template(self): class TestFindAll: @os_helper.skip_unless_symlink - def test_missing_symlink(self): - with os_helper.temp_cwd(): - os.symlink('foo', 'bar') - assert filelist.findall() == [] + def test_missing_symlink(self, temp_cwd): + os.symlink('foo', 'bar') + assert filelist.findall() == [] - def test_basic_discovery(self): + def test_basic_discovery(self, temp_cwd): """ When findall is called with no parameters or with '.' as the parameter, the dot should be omitted from the results. """ - with os_helper.temp_cwd(): - os.mkdir('foo') - file1 = os.path.join('foo', 'file1.txt') - os_helper.create_empty_file(file1) - os.mkdir('bar') - file2 = os.path.join('bar', 'file2.txt') - os_helper.create_empty_file(file2) - expected = [file2, file1] - assert sorted(filelist.findall()) == expected - - def test_non_local_discovery(self): + jaraco.path.build({'foo': {'file1.txt': ''}, 'bar': {'file2.txt': ''}}) + file1 = os.path.join('foo', 'file1.txt') + file2 = os.path.join('bar', 'file2.txt') + expected = [file2, file1] + assert sorted(filelist.findall()) == expected + + def test_non_local_discovery(self, tmp_path): """ When findall is called with another path, the full path name should be returned. """ - with os_helper.temp_dir() as temp_dir: - file1 = os.path.join(temp_dir, 'file1.txt') - os_helper.create_empty_file(file1) - expected = [file1] - assert filelist.findall(temp_dir) == expected + filename = tmp_path / 'file1.txt' + filename.write_text('') + expected = [str(filename)] + assert filelist.findall(tmp_path) == expected @os_helper.skip_unless_symlink - def test_symlink_loop(self): - with os_helper.temp_dir() as temp_dir: - link = os.path.join(temp_dir, 'link-to-parent') - content = os.path.join(temp_dir, 'somefile') - os_helper.create_empty_file(content) - os.symlink('.', link) - files = filelist.findall(temp_dir) - assert len(files) == 1 + def test_symlink_loop(self, tmp_path): + tmp_path.joinpath('link-to-parent').symlink_to('.') + tmp_path.joinpath('somefile').write_text('') + files = filelist.findall(tmp_path) + assert len(files) == 1 diff --git a/setuptools/_distutils/tests/test_spawn.py b/setuptools/_distutils/tests/test_spawn.py index d2a898ed3f..5da499777a 100644 --- a/setuptools/_distutils/tests/test_spawn.py +++ b/setuptools/_distutils/tests/test_spawn.py @@ -6,6 +6,8 @@ from test.support import unix_shell +import path + from . import py38compat as os_helper from distutils.spawn import find_executable @@ -44,83 +46,82 @@ def test_spawn(self): os.chmod(exe, 0o777) spawn([exe]) # should work without any error - def test_find_executable(self): - with os_helper.temp_dir() as tmp_dir: - # use TESTFN to get a pseudo-unique filename - program_noeext = os_helper.TESTFN - # Give the temporary program an ".exe" suffix for all. - # It's needed on Windows and not harmful on other platforms. - program = program_noeext + ".exe" - - filename = os.path.join(tmp_dir, program) - with open(filename, "wb"): - pass - os.chmod(filename, stat.S_IXUSR) - - # test path parameter - rv = find_executable(program, path=tmp_dir) + def test_find_executable(self, tmp_path): + program_noeext = 'program' + # Give the temporary program an ".exe" suffix for all. + # It's needed on Windows and not harmful on other platforms. + program = program_noeext + ".exe" + + program_path = tmp_path / program + program_path.write_text("") + program_path.chmod(stat.S_IXUSR) + filename = str(program_path) + tmp_dir = path.Path(tmp_path) + + # test path parameter + rv = find_executable(program, path=tmp_dir) + assert rv == filename + + if sys.platform == 'win32': + # test without ".exe" extension + rv = find_executable(program_noeext, path=tmp_dir) assert rv == filename - if sys.platform == 'win32': - # test without ".exe" extension - rv = find_executable(program_noeext, path=tmp_dir) - assert rv == filename - - # test find in the current directory - with os_helper.change_cwd(tmp_dir): + # test find in the current directory + with tmp_dir: + rv = find_executable(program) + assert rv == program + + # test non-existent program + dont_exist_program = "dontexist_" + program + rv = find_executable(dont_exist_program, path=tmp_dir) + assert rv is None + + # PATH='': no match, except in the current directory + 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 == program - - # test non-existent program - dont_exist_program = "dontexist_" + program - rv = find_executable(dont_exist_program, path=tmp_dir) - assert rv is None - - # PATH='': no match, except in the current directory - 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 - - # look in current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - assert rv == program - - # PATH=':': explicitly looks in the current directory - 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', ''): + assert rv is None + + # look in current directory + with tmp_dir: rv = find_executable(program) - assert rv is None + assert rv == program + + # PATH=':': explicitly looks in the current directory + 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 - # look in current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - assert rv == program + # look in current directory + with tmp_dir: + rv = find_executable(program) + assert rv == program - # missing PATH: test os.confstr("CS_PATH") and os.defpath - with os_helper.EnvironmentVarGuard() as env: - env.pop('PATH', None) + # missing PATH: test os.confstr("CS_PATH") and os.defpath + with os_helper.EnvironmentVarGuard() as env: + env.pop('PATH', None) - # without confstr - 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 + # without confstr + 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 confstr - 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 + # with confstr + 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 def test_spawn_missing_exe(self): with pytest.raises(DistutilsExecError) as ctx: diff --git a/setuptools/_distutils/tests/test_sysconfig.py b/setuptools/_distutils/tests/test_sysconfig.py index f1759839bb..66f92c2ae0 100644 --- a/setuptools/_distutils/tests/test_sysconfig.py +++ b/setuptools/_distutils/tests/test_sysconfig.py @@ -1,13 +1,14 @@ """Tests for distutils.sysconfig.""" import contextlib import os -import shutil import subprocess import sys -import textwrap +import pathlib import pytest import jaraco.envs +import path +from jaraco.text import trim import distutils from distutils import sysconfig @@ -15,33 +16,23 @@ from distutils.unixccompiler import UnixCCompiler from test.support import swap_item -from .py38compat import TESTFN +from . import py37compat @pytest.mark.usefixtures('save_env') -@pytest.mark.usefixtures('cleanup_testfn') class TestSysconfig: - def cleanup_testfn(self): - if os.path.isfile(TESTFN): - os.remove(TESTFN) - elif os.path.isdir(TESTFN): - shutil.rmtree(TESTFN) - def test_get_config_h_filename(self): config_h = sysconfig.get_config_h_filename() - assert os.path.isfile(config_h), config_h + assert os.path.isfile(config_h) @pytest.mark.skipif("platform.system() == 'Windows'") @pytest.mark.skipif("sys.implementation.name != 'cpython'") def test_get_makefile_filename(self): makefile = sysconfig.get_makefile_filename() - assert os.path.isfile(makefile), makefile + assert os.path.isfile(makefile) - def test_get_python_lib(self): - # XXX doesn't work on Linux when Python was never installed before - # self.assertTrue(os.path.isdir(lib_dir), lib_dir) - # test for pythonxx.lib? - assert sysconfig.get_python_lib() != sysconfig.get_python_lib(prefix=TESTFN) + def test_get_python_lib(self, tmp_path): + assert sysconfig.get_python_lib() != sysconfig.get_python_lib(prefix=tmp_path) def test_get_config_vars(self): cvars = sysconfig.get_config_vars() @@ -49,33 +40,39 @@ def test_get_config_vars(self): assert cvars @pytest.mark.skipif('sysconfig.IS_PYPY') - @pytest.mark.xfail(reason="broken") - def test_srcdir(self): - # See Issues #15322, #15364. - srcdir = sysconfig.get_config_var('srcdir') + @pytest.mark.skipif('sysconfig.python_build') + @pytest.mark.xfail('platform.system() == "Windows"') + def test_srcdir_simple(self): + # See #15364. + srcdir = pathlib.Path(sysconfig.get_config_var('srcdir')) - assert os.path.isabs(srcdir), srcdir - assert os.path.isdir(srcdir), srcdir + assert srcdir.absolute() + assert srcdir.is_dir() - if sysconfig.python_build: - # The python executable has not been installed so srcdir - # should be a full source checkout. - Python_h = os.path.join(srcdir, 'Include', 'Python.h') - assert os.path.exists(Python_h), Python_h - assert sysconfig._is_python_source_dir(srcdir) - elif os.name == 'posix': - assert os.path.dirname(sysconfig.get_makefile_filename()) == srcdir + makefile = pathlib.Path(sysconfig.get_makefile_filename()) + assert makefile.parent.samefile(srcdir) + + @pytest.mark.skipif('sysconfig.IS_PYPY') + @pytest.mark.skipif('not sysconfig.python_build') + def test_srcdir_python_build(self): + # See #15364. + srcdir = pathlib.Path(sysconfig.get_config_var('srcdir')) + + # The python executable has not been installed so srcdir + # should be a full source checkout. + Python_h = srcdir.joinpath('Include', 'Python.h') + assert Python_h.is_file() + assert sysconfig._is_python_source_dir(srcdir) + assert sysconfig._is_python_source_dir(str(srcdir)) def test_srcdir_independent_of_cwd(self): - # srcdir should be independent of the current working directory - # See Issues #15322, #15364. + """ + srcdir should be independent of the current working directory + """ + # See #15364. srcdir = sysconfig.get_config_var('srcdir') - cwd = os.getcwd() - try: - os.chdir('..') + with path.Path('..'): srcdir2 = sysconfig.get_config_var('srcdir') - finally: - os.chdir(cwd) assert srcdir == srcdir2 def customize_compiler(self): @@ -169,26 +166,32 @@ def test_customize_compiler(self): assert comp.shared_lib_extension == 'sc_shutil_suffix' assert 'ranlib' not in comp.exes - def test_parse_makefile_base(self): - self.makefile = TESTFN - fd = open(self.makefile, 'w') - try: - fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=LIB'" '\n') - fd.write('VAR=$OTHER\nOTHER=foo') - finally: - fd.close() - d = sysconfig.parse_makefile(self.makefile) + def test_parse_makefile_base(self, tmp_path): + makefile = tmp_path / 'Makefile' + makefile.write_text( + trim( + """ + CONFIG_ARGS= '--arg1=optarg1' 'ENV=LIB' + VAR=$OTHER + OTHER=foo + """ + ) + ) + d = sysconfig.parse_makefile(makefile) assert d == {'CONFIG_ARGS': "'--arg1=optarg1' 'ENV=LIB'", 'OTHER': 'foo'} - def test_parse_makefile_literal_dollar(self): - self.makefile = TESTFN - fd = open(self.makefile, 'w') - try: - fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=\$$LIB'" '\n') - fd.write('VAR=$OTHER\nOTHER=foo') - finally: - fd.close() - d = sysconfig.parse_makefile(self.makefile) + def test_parse_makefile_literal_dollar(self, tmp_path): + makefile = tmp_path / 'Makefile' + makefile.write_text( + trim( + """ + CONFIG_ARGS= '--arg1=optarg1' 'ENV=\\$$LIB' + VAR=$OTHER + OTHER=foo + """ + ) + ) + d = sysconfig.parse_makefile(makefile) assert d == {'CONFIG_ARGS': r"'--arg1=optarg1' 'ENV=\$LIB'", 'OTHER': 'foo'} def test_sysconfig_module(self): @@ -231,24 +234,24 @@ def test_SO_deprecation(self): with pytest.warns(DeprecationWarning): sysconfig.get_config_var('SO') - def test_customize_compiler_before_get_config_vars(self): + def test_customize_compiler_before_get_config_vars(self, tmp_path): # Issue #21923: test that a Distribution compiler # instance can be called without an explicit call to # get_config_vars(). - with open(TESTFN, 'w') as f: - f.writelines( - textwrap.dedent( - '''\ + file = tmp_path / 'file' + file.write_text( + trim( + """ from distutils.core import Distribution config = Distribution().get_command_obj('config') # try_compile may pass or it may fail if no compiler # is found but it should not raise an exception. rc = config.try_compile('int x;') - ''' - ) + """ ) + ) p = subprocess.Popen( - [str(sys.executable), TESTFN], + py37compat.subprocess_args(sys.executable, file), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, @@ -278,11 +281,11 @@ def test_win_ext_suffix(self): '\\PCbuild\\'.casefold() not in sys.executable.casefold(), reason='Need sys.executable to be in a source tree', ) - def test_win_build_venv_from_source_tree(self): + def test_win_build_venv_from_source_tree(self, tmp_path): """Ensure distutils.sysconfig detects venvs from source tree builds.""" env = jaraco.envs.VEnv() env.create_opts = env.clean_opts - env.root = TESTFN + env.root = tmp_path env.ensure_env() cmd = [ env.exe(),