import sys
import os
import re
+import pathlib
+import contextlib
from email import message_from_file
try:
should be parsed. The filenames returned are guaranteed to exist
(modulo nasty race conditions).
- There are three possible config files: distutils.cfg in the
- Distutils installation directory (ie. where the top-level
- Distutils __inst__.py file lives), a file in the user's home
- directory named .pydistutils.cfg on Unix and pydistutils.cfg
- on Windows/Mac; and setup.cfg in the current directory.
-
- The file in the user's home directory can be disabled with the
- --no-user-cfg option.
+ There are multiple possible config files:
+ - distutils.cfg in the Distutils installation directory (i.e.
+ where the top-level Distutils __inst__.py file lives)
+ - a file in the user's home directory named .pydistutils.cfg
+ on Unix and pydistutils.cfg on Windows/Mac; may be disabled
+ with the ``--no-user-cfg`` option
+ - setup.cfg in the current directory
+ - a file named by an environment variable
"""
- files = []
check_environ()
+ files = [str(path) for path in self._gen_paths() if path.is_file()]
- # Where to look for the system-wide Distutils config file
- sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
+ if DEBUG:
+ self.announce("using config files: %s" % ', '.join(files))
- # Look for the system config file
- sys_file = os.path.join(sys_dir, "distutils.cfg")
- if os.path.isfile(sys_file):
- files.append(sys_file)
+ return files
- # What to call the per-user config file
- if os.name == 'posix':
- user_filename = ".pydistutils.cfg"
- else:
- user_filename = "pydistutils.cfg"
+ def _gen_paths(self):
+ # The system-wide Distutils config file
+ sys_dir = pathlib.Path(sys.modules['distutils'].__file__).parent
+ yield sys_dir / "distutils.cfg"
- # And look for the user config file
+ # The per-user config file
+ prefix = '.' * (os.name == 'posix')
+ filename = prefix + 'pydistutils.cfg'
if self.want_user_cfg:
- user_file = os.path.join(os.path.expanduser('~'), user_filename)
- if os.path.isfile(user_file):
- files.append(user_file)
+ yield pathlib.Path('~').expanduser() / filename
# All platforms support local setup.cfg
- local_file = "setup.cfg"
- if os.path.isfile(local_file):
- files.append(local_file)
+ yield pathlib.Path('setup.cfg')
- if DEBUG:
- self.announce("using config files: %s" % ', '.join(files))
-
- return files
+ # Additional config indicated in the environment
+ with contextlib.suppress(TypeError):
+ yield pathlib.Path(os.getenv("DIST_EXTRA_CONFIG"))
def parse_config_files(self, filenames=None): # noqa: C901
from configparser import ConfigParser
import unittest.mock as mock
import pytest
+import jaraco.path
from distutils.dist import Distribution, fix_help_options
from distutils.cmd import Command
from distutils import log
+pydistutils_cfg = '.' * (os.name == 'posix') + 'pydistutils.cfg'
+
+
class test_dist(Command):
"""Sample distutils extension command."""
fakepath = '/somedir'
- with open(TESTFN, "w") as f:
- print(
- (
- "[install]\n"
- "install-base = {0}\n"
- "install-platbase = {0}\n"
- "install-lib = {0}\n"
- "install-platlib = {0}\n"
- "install-purelib = {0}\n"
- "install-headers = {0}\n"
- "install-scripts = {0}\n"
- "install-data = {0}\n"
- "prefix = {0}\n"
- "exec-prefix = {0}\n"
- "home = {0}\n"
- "user = {0}\n"
- "root = {0}"
- ).format(fakepath),
- file=f,
- )
+ jaraco.path.build(
+ {
+ TESTFN: f"""
+ [install]
+ install-base = {fakepath}
+ install-platbase = {fakepath}
+ install-lib = {fakepath}
+ install-platlib = {fakepath}
+ install-purelib = {fakepath}
+ install-headers = {fakepath}
+ install-scripts = {fakepath}
+ install-data = {fakepath}
+ prefix = {fakepath}
+ exec-prefix = {fakepath}
+ home = {fakepath}
+ user = {fakepath}
+ root = {fakepath}
+ """,
+ }
+ )
# Base case: Not in a Virtual Environment
with mock.patch.multiple(sys, prefix='/a', base_prefix='/a'):
def test_command_packages_configfile(self, request, clear_argv):
sys.argv.append("build")
request.addfinalizer(functools.partial(os.unlink, TESTFN))
- f = open(TESTFN, "w")
- try:
- print("[global]", file=f)
- print("command_packages = foo.bar, splat", file=f)
- finally:
- f.close()
+ jaraco.path.build(
+ {
+ TESTFN: """
+ [global]
+ command_packages = foo.bar, splat
+ """,
+ }
+ )
d = self.create_distribution([TESTFN])
assert d.get_command_packages() == ["distutils.command", "foo.bar", "splat"]
with pytest.raises(ValueError):
dist.announce(args, kwargs)
- def test_find_config_files_disable(self):
+ def test_find_config_files_disable(self, temp_home):
# Ticket #1180: Allow user to disable their home config file.
- temp_home = self.mkdtemp()
- if os.name == 'posix':
- user_filename = os.path.join(temp_home, ".pydistutils.cfg")
- else:
- user_filename = os.path.join(temp_home, "pydistutils.cfg")
-
- with open(user_filename, 'w') as f:
- f.write('[distutils]\n')
-
- def _expander(path):
- return temp_home
+ jaraco.path.build({pydistutils_cfg: '[distutils]\n'}, temp_home)
- old_expander = os.path.expanduser
- os.path.expanduser = _expander
- try:
- d = Distribution()
- all_files = d.find_config_files()
+ d = Distribution()
+ all_files = d.find_config_files()
- d = Distribution(attrs={'script_args': ['--no-user-cfg']})
- files = d.find_config_files()
- finally:
- os.path.expanduser = old_expander
+ d = Distribution(attrs={'script_args': ['--no-user-cfg']})
+ files = d.find_config_files()
# make sure --no-user-cfg disables the user cfg file
assert len(all_files) - 1 == len(files)
@pytest.mark.usefixtures('save_env')
@pytest.mark.usefixtures('save_argv')
-class MetadataTestCase(support.TempdirManager):
+class TestMetadata(support.TempdirManager):
def format_metadata(self, dist):
sio = io.StringIO()
dist.metadata.write_pkg_file(sio)
meta = meta.replace('\n' + 8 * ' ', '\n')
assert long_desc in meta
- def test_custom_pydistutils(self):
- # fixes #2166
- # make sure pydistutils.cfg is found
- if os.name == 'posix':
- user_filename = ".pydistutils.cfg"
- else:
- user_filename = "pydistutils.cfg"
-
- temp_dir = self.mkdtemp()
- user_filename = os.path.join(temp_dir, user_filename)
- f = open(user_filename, 'w')
- try:
- f.write('.')
- finally:
- f.close()
-
- try:
- dist = Distribution()
-
- # linux-style
- if sys.platform in ('linux', 'darwin'):
- os.environ['HOME'] = temp_dir
- files = dist.find_config_files()
- assert user_filename in files
-
- # win32-style
- if sys.platform == 'win32':
- # home drive should be found
- os.environ['USERPROFILE'] = temp_dir
- files = dist.find_config_files()
- assert user_filename in files, '{!r} not found in {!r}'.format(
- user_filename, files
- )
- finally:
- os.remove(user_filename)
+ def test_custom_pydistutils(self, temp_home):
+ """
+ pydistutils.cfg is found
+ """
+ jaraco.path.build({pydistutils_cfg: ''}, temp_home)
+ config_path = temp_home / pydistutils_cfg
+
+ assert str(config_path) in Distribution().find_config_files()
+
+ def test_extra_pydistutils(self, monkeypatch, tmp_path):
+ jaraco.path.build({'overrides.cfg': ''}, tmp_path)
+ filename = tmp_path / 'overrides.cfg'
+ monkeypatch.setenv('DIST_EXTRA_CONFIG', str(filename))
+ assert str(filename) in Distribution().find_config_files()
def test_fix_help_options(self):
help_tuples = [('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
assert fancy_options[0] == ('a', 'b', 'c')
assert fancy_options[1] == (1, 2, 3)
- def test_show_help(self):
+ def test_show_help(self, request):
# smoke test, just makes sure some help is displayed
- self.addCleanup(log.set_threshold, log._global_log.threshold)
+ reset_log = functools.partial(log.set_threshold, log._global_log.threshold)
+ request.addfinalizer(reset_log)
dist = Distribution()
sys.argv = []
dist.help = 1