Skip to content

Commit 401c184

Browse files
authored
Merge pull request #3617 from pypa/distutils-6852b20
Merge with pypa/distutils@6852b20
2 parents 273993d + 58b9692 commit 401c184

File tree

12 files changed

+251
-234
lines changed

12 files changed

+251
-234
lines changed

changelog.d/3617.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Merge with pypa/distutils@6852b20 including fix for pypa/distutils#181.

setuptools/_distutils/dist.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ def find_config_files(self):
334334
- a file named by an environment variable
335335
"""
336336
check_environ()
337-
files = [str(path) for path in self._gen_paths() if path.is_file()]
337+
files = [str(path) for path in self._gen_paths() if os.path.isfile(path)]
338338

339339
if DEBUG:
340340
self.announce("using config files: %s" % ', '.join(files))

setuptools/_distutils/sysconfig.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import re
1414
import sys
1515
import sysconfig
16+
import pathlib
1617

1718
from .errors import DistutilsPlatformError
1819
from . import py39compat
@@ -40,14 +41,13 @@
4041
project_base = os.getcwd()
4142

4243

43-
# python_build: (Boolean) if true, we're either building Python or
44-
# building an extension with an un-installed Python, so we use
45-
# different (hard-wired) directories.
4644
def _is_python_source_dir(d):
47-
for fn in ("Setup", "Setup.local"):
48-
if os.path.isfile(os.path.join(d, "Modules", fn)):
49-
return True
50-
return False
45+
"""
46+
Return True if the target directory appears to point to an
47+
un-installed Python.
48+
"""
49+
modules = pathlib.Path(d).joinpath('Modules')
50+
return any(modules.joinpath(fn).is_file() for fn in ('Setup', 'Setup.local'))
5151

5252

5353
_sys_home = getattr(sys, '_home', None)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import os
2+
import sys
3+
import platform
4+
5+
6+
def subprocess_args_compat(*args):
7+
return list(map(os.fspath, args))
8+
9+
10+
def subprocess_args_passthrough(*args):
11+
return list(args)
12+
13+
14+
subprocess_args = (
15+
subprocess_args_compat
16+
if platform.system() == "Windows" and sys.version_info < (3, 8)
17+
else subprocess_args_passthrough
18+
)

setuptools/_distutils/tests/py38compat.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,19 @@
1818

1919
try:
2020
from test.support.os_helper import (
21-
change_cwd,
2221
rmtree,
2322
EnvironmentVarGuard,
24-
TESTFN,
2523
unlink,
2624
skip_unless_symlink,
2725
temp_dir,
28-
create_empty_file,
29-
temp_cwd,
3026
)
3127
except (ModuleNotFoundError, ImportError):
3228
from test.support import (
33-
change_cwd,
3429
rmtree,
3530
EnvironmentVarGuard,
36-
TESTFN,
3731
unlink,
3832
skip_unless_symlink,
3933
temp_dir,
40-
create_empty_file,
41-
temp_cwd,
4234
)
4335

4436

setuptools/_distutils/tests/test_archive_util.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import pathlib
1010

1111
import pytest
12+
import path
1213

1314
from distutils import archive_util
1415
from distutils.archive_util import (
@@ -23,7 +24,6 @@
2324
from test.support import patch
2425
from .unix_compat import require_unix_id, require_uid_0, grp, pwd, UID_0_SUPPORT
2526

26-
from .py38compat import change_cwd
2727
from .py38compat import check_warnings
2828

2929

@@ -95,7 +95,7 @@ def _make_tarball(self, tmpdir, target_name, suffix, **kwargs):
9595
base_name = os.path.join(tmpdir2, target_name)
9696

9797
# working with relative paths to avoid tar warnings
98-
with change_cwd(tmpdir):
98+
with path.Path(tmpdir):
9999
make_tarball(splitdrive(base_name)[1], 'dist', **kwargs)
100100

101101
# check if the compressed tarball was created
@@ -227,7 +227,7 @@ def test_make_zipfile(self):
227227
# creating something to tar
228228
tmpdir = self._create_files()
229229
base_name = os.path.join(self.mkdtemp(), 'archive')
230-
with change_cwd(tmpdir):
230+
with path.Path(tmpdir):
231231
make_zipfile(base_name, 'dist')
232232

233233
# check if the compressed tarball was created
@@ -253,7 +253,7 @@ def fake_zipfile(*a, **kw):
253253
# create something to tar and compress
254254
tmpdir = self._create_files()
255255
base_name = os.path.join(self.mkdtemp(), 'archive')
256-
with change_cwd(tmpdir):
256+
with path.Path(tmpdir):
257257
make_zipfile(base_name, 'dist')
258258

259259
tarball = base_name + '.zip'

setuptools/_distutils/tests/test_build_ext.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
import tempfile
99
import importlib
1010
import shutil
11+
import re
12+
13+
import path
14+
import pytest
1115

1216
from distutils.core import Distribution
1317
from distutils.command.build_ext import build_ext
@@ -27,10 +31,7 @@
2731
)
2832

2933
from test import support
30-
from . import py38compat as os_helper
3134
from . import py38compat as import_helper
32-
import pytest
33-
import re
3435

3536

3637
@pytest.fixture()
@@ -47,7 +48,7 @@ def user_site_dir(request):
4748
# bpo-30132: On Windows, a .pdb file may be created in the current
4849
# working directory. Create a temporary working directory to cleanup
4950
# everything at the end of the test.
50-
with os_helper.change_cwd(self.tmp_dir):
51+
with path.Path(self.tmp_dir):
5152
yield
5253

5354
site.USER_BASE = orig_user_base

setuptools/_distutils/tests/test_core.py

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import pytest
1010

11-
from . import py38compat as os_helper
1211
from distutils.dist import Distribution
1312

1413
# setup script that uses __file__
@@ -61,65 +60,63 @@ def save_stdout(monkeypatch):
6160
monkeypatch.setattr(sys, 'stdout', sys.stdout)
6261

6362

63+
@pytest.fixture
64+
def temp_file(tmp_path):
65+
return tmp_path / 'file'
66+
67+
6468
@pytest.mark.usefixtures('save_env')
6569
@pytest.mark.usefixtures('save_argv')
66-
@pytest.mark.usefixtures('cleanup_testfn')
6770
class TestCore:
68-
def write_setup(self, text, path=os_helper.TESTFN):
69-
f = open(path, "w")
70-
try:
71-
f.write(text)
72-
finally:
73-
f.close()
74-
return path
75-
76-
def test_run_setup_provides_file(self):
71+
def test_run_setup_provides_file(self, temp_file):
7772
# Make sure the script can use __file__; if that's missing, the test
7873
# setup.py script will raise NameError.
79-
distutils.core.run_setup(self.write_setup(setup_using___file__))
74+
temp_file.write_text(setup_using___file__)
75+
distutils.core.run_setup(temp_file)
8076

81-
def test_run_setup_preserves_sys_argv(self):
77+
def test_run_setup_preserves_sys_argv(self, temp_file):
8278
# Make sure run_setup does not clobber sys.argv
8379
argv_copy = sys.argv.copy()
84-
distutils.core.run_setup(self.write_setup(setup_does_nothing))
80+
temp_file.write_text(setup_does_nothing)
81+
distutils.core.run_setup(temp_file)
8582
assert sys.argv == argv_copy
8683

87-
def test_run_setup_defines_subclass(self):
84+
def test_run_setup_defines_subclass(self, temp_file):
8885
# Make sure the script can use __file__; if that's missing, the test
8986
# setup.py script will raise NameError.
90-
dist = distutils.core.run_setup(self.write_setup(setup_defines_subclass))
87+
temp_file.write_text(setup_defines_subclass)
88+
dist = distutils.core.run_setup(temp_file)
9189
install = dist.get_command_obj('install')
9290
assert 'cmd' in install.sub_commands
9391

94-
def test_run_setup_uses_current_dir(self):
95-
# This tests that the setup script is run with the current directory
96-
# as its own current directory; this was temporarily broken by a
97-
# previous patch when TESTFN did not use the current directory.
92+
def test_run_setup_uses_current_dir(self, tmp_path):
93+
"""
94+
Test that the setup script is run with the current directory
95+
as its own current directory.
96+
"""
9897
sys.stdout = io.StringIO()
9998
cwd = os.getcwd()
10099

101100
# Create a directory and write the setup.py file there:
102-
os.mkdir(os_helper.TESTFN)
103-
setup_py = os.path.join(os_helper.TESTFN, "setup.py")
104-
distutils.core.run_setup(self.write_setup(setup_prints_cwd, path=setup_py))
101+
setup_py = tmp_path / 'setup.py'
102+
setup_py.write_text(setup_prints_cwd)
103+
distutils.core.run_setup(setup_py)
105104

106105
output = sys.stdout.getvalue()
107106
if output.endswith("\n"):
108107
output = output[:-1]
109108
assert cwd == output
110109

111-
def test_run_setup_within_if_main(self):
112-
dist = distutils.core.run_setup(
113-
self.write_setup(setup_within_if_main), stop_after="config"
114-
)
110+
def test_run_setup_within_if_main(self, temp_file):
111+
temp_file.write_text(setup_within_if_main)
112+
dist = distutils.core.run_setup(temp_file, stop_after="config")
115113
assert isinstance(dist, Distribution)
116114
assert dist.get_name() == "setup_within_if_main"
117115

118-
def test_run_commands(self):
116+
def test_run_commands(self, temp_file):
119117
sys.argv = ['setup.py', 'build']
120-
dist = distutils.core.run_setup(
121-
self.write_setup(setup_within_if_main), stop_after="commandline"
122-
)
118+
temp_file.write_text(setup_within_if_main)
119+
dist = distutils.core.run_setup(temp_file, stop_after="commandline")
123120
assert 'build' not in dist.have_run
124121
distutils.core.run_commands(dist)
125122
assert 'build' in dist.have_run

setuptools/_distutils/tests/test_dist.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from distutils.cmd import Command
1515

1616
from test.support import captured_stdout, captured_stderr
17-
from .py38compat import TESTFN
1817
from distutils.tests import support
1918
from distutils import log
2019

@@ -95,15 +94,15 @@ def test_command_packages_cmdline(self, clear_argv):
9594
'distutils' not in Distribution.parse_config_files.__module__,
9695
reason='Cannot test when virtualenv has monkey-patched Distribution',
9796
)
98-
def test_venv_install_options(self, request):
97+
def test_venv_install_options(self, tmp_path):
9998
sys.argv.append("install")
100-
request.addfinalizer(functools.partial(os.unlink, TESTFN))
99+
file = str(tmp_path / 'file')
101100

102101
fakepath = '/somedir'
103102

104103
jaraco.path.build(
105104
{
106-
TESTFN: f"""
105+
file: f"""
107106
[install]
108107
install-base = {fakepath}
109108
install-platbase = {fakepath}
@@ -124,9 +123,9 @@ def test_venv_install_options(self, request):
124123

125124
# Base case: Not in a Virtual Environment
126125
with mock.patch.multiple(sys, prefix='/a', base_prefix='/a'):
127-
d = self.create_distribution([TESTFN])
126+
d = self.create_distribution([file])
128127

129-
option_tuple = (TESTFN, fakepath)
128+
option_tuple = (file, fakepath)
130129

131130
result_dict = {
132131
'install_base': option_tuple,
@@ -153,35 +152,35 @@ def test_venv_install_options(self, request):
153152

154153
# Test case: In a Virtual Environment
155154
with mock.patch.multiple(sys, prefix='/a', base_prefix='/b'):
156-
d = self.create_distribution([TESTFN])
155+
d = self.create_distribution([file])
157156

158157
for key in result_dict.keys():
159158
assert key not in d.command_options.get('install', {})
160159

161-
def test_command_packages_configfile(self, request, clear_argv):
160+
def test_command_packages_configfile(self, tmp_path, clear_argv):
162161
sys.argv.append("build")
163-
request.addfinalizer(functools.partial(os.unlink, TESTFN))
162+
file = str(tmp_path / "file")
164163
jaraco.path.build(
165164
{
166-
TESTFN: """
165+
file: """
167166
[global]
168167
command_packages = foo.bar, splat
169168
""",
170169
}
171170
)
172171

173-
d = self.create_distribution([TESTFN])
172+
d = self.create_distribution([file])
174173
assert d.get_command_packages() == ["distutils.command", "foo.bar", "splat"]
175174

176175
# ensure command line overrides config:
177176
sys.argv[1:] = ["--command-packages", "spork", "build"]
178-
d = self.create_distribution([TESTFN])
177+
d = self.create_distribution([file])
179178
assert d.get_command_packages() == ["distutils.command", "spork"]
180179

181180
# Setting --command-packages to '' should cause the default to
182181
# be used even if a config file specified something else:
183182
sys.argv[1:] = ["--command-packages", "", "build"]
184-
d = self.create_distribution([TESTFN])
183+
d = self.create_distribution([file])
185184
assert d.get_command_packages() == ["distutils.command"]
186185

187186
def test_empty_options(self, request):
@@ -259,6 +258,18 @@ def test_find_config_files_disable(self, temp_home):
259258
# make sure --no-user-cfg disables the user cfg file
260259
assert len(all_files) - 1 == len(files)
261260

261+
@pytest.mark.skipif(
262+
'platform.system() == "Windows"',
263+
reason='Windows does not honor chmod 000',
264+
)
265+
def test_find_config_files_permission_error(self, fake_home):
266+
"""
267+
Finding config files should not fail when directory is inaccessible.
268+
"""
269+
fake_home.joinpath(pydistutils_cfg).write_text('')
270+
fake_home.chmod(0o000)
271+
Distribution().find_config_files()
272+
262273

263274
@pytest.mark.usefixtures('save_env')
264275
@pytest.mark.usefixtures('save_argv')

0 commit comments

Comments
 (0)