summaryrefslogtreecommitdiff
path: root/setuptools/_distutils
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2022-02-12 05:15:38 -0500
committerJason R. Coombs <jaraco@jaraco.com>2022-02-12 05:15:38 -0500
commitd7b783a4b8b01e58135e40bd9a1db8a82c090982 (patch)
tree19f75949414a1f6942e59fd69e9a1e86f469ea5a /setuptools/_distutils
parent5b75de07169ef13952a5ab48e0b8bc15f31d0c37 (diff)
parentce9ddd528a9e2507d3ae794f4d26f6a46d06d025 (diff)
downloadpython-setuptools-git-d7b783a4b8b01e58135e40bd9a1db8a82c090982.tar.gz
Merge branch 'main' into debt/remove-legacy-version
Diffstat (limited to 'setuptools/_distutils')
-rw-r--r--setuptools/_distutils/__init__.py11
-rw-r--r--setuptools/_distutils/_collections.py56
-rw-r--r--setuptools/_distutils/_msvccompiler.py4
-rw-r--r--setuptools/_distutils/bcppcompiler.py2
-rw-r--r--setuptools/_distutils/command/bdist_msi.py2
-rw-r--r--setuptools/_distutils/command/build_ext.py4
-rw-r--r--setuptools/_distutils/command/check.py2
-rw-r--r--setuptools/_distutils/command/install.py263
-rw-r--r--setuptools/_distutils/command/install_egg_info.py15
-rw-r--r--setuptools/_distutils/core.py55
-rw-r--r--setuptools/_distutils/cygwinccompiler.py156
-rw-r--r--setuptools/_distutils/log.py6
-rw-r--r--setuptools/_distutils/msvc9compiler.py6
-rw-r--r--setuptools/_distutils/msvccompiler.py2
-rw-r--r--setuptools/_distutils/spawn.py2
-rw-r--r--setuptools/_distutils/sysconfig.py67
-rw-r--r--setuptools/_distutils/tests/py38compat.py9
-rw-r--r--setuptools/_distutils/tests/test_archive_util.py14
-rw-r--r--setuptools/_distutils/tests/test_bdist.py2
-rw-r--r--setuptools/_distutils/tests/test_bdist_dumb.py2
-rw-r--r--setuptools/_distutils/tests/test_bdist_msi.py2
-rw-r--r--setuptools/_distutils/tests/test_bdist_rpm.py11
-rw-r--r--setuptools/_distutils/tests/test_bdist_wininst.py2
-rw-r--r--setuptools/_distutils/tests/test_build.py2
-rw-r--r--setuptools/_distutils/tests/test_build_clib.py2
-rw-r--r--setuptools/_distutils/tests/test_build_ext.py12
-rw-r--r--setuptools/_distutils/tests/test_build_py.py2
-rw-r--r--setuptools/_distutils/tests/test_build_scripts.py2
-rw-r--r--setuptools/_distutils/tests/test_check.py2
-rw-r--r--setuptools/_distutils/tests/test_clean.py2
-rw-r--r--setuptools/_distutils/tests/test_cmd.py2
-rw-r--r--setuptools/_distutils/tests/test_config.py4
-rw-r--r--setuptools/_distutils/tests/test_config_cmd.py2
-rw-r--r--setuptools/_distutils/tests/test_core.py27
-rw-r--r--setuptools/_distutils/tests/test_cygwinccompiler.py70
-rw-r--r--setuptools/_distutils/tests/test_dep_util.py2
-rw-r--r--setuptools/_distutils/tests/test_dir_util.py2
-rw-r--r--setuptools/_distutils/tests/test_dist.py4
-rw-r--r--setuptools/_distutils/tests/test_extension.py2
-rw-r--r--setuptools/_distutils/tests/test_file_util.py2
-rw-r--r--setuptools/_distutils/tests/test_filelist.py4
-rw-r--r--setuptools/_distutils/tests/test_install.py19
-rw-r--r--setuptools/_distutils/tests/test_install_data.py2
-rw-r--r--setuptools/_distutils/tests/test_install_headers.py2
-rw-r--r--setuptools/_distutils/tests/test_install_lib.py2
-rw-r--r--setuptools/_distutils/tests/test_install_scripts.py2
-rw-r--r--setuptools/_distutils/tests/test_log.py2
-rw-r--r--setuptools/_distutils/tests/test_msvc9compiler.py2
-rw-r--r--setuptools/_distutils/tests/test_msvccompiler.py4
-rw-r--r--setuptools/_distutils/tests/test_register.py2
-rw-r--r--setuptools/_distutils/tests/test_sdist.py13
-rw-r--r--setuptools/_distutils/tests/test_spawn.py2
-rw-r--r--setuptools/_distutils/tests/test_sysconfig.py17
-rw-r--r--setuptools/_distutils/tests/test_text_file.py2
-rw-r--r--setuptools/_distutils/tests/test_unixccompiler.py9
-rw-r--r--setuptools/_distutils/tests/test_upload.py2
-rw-r--r--setuptools/_distutils/tests/test_util.py127
-rw-r--r--setuptools/_distutils/tests/test_version.py10
-rw-r--r--setuptools/_distutils/tests/unix_compat.py16
-rw-r--r--setuptools/_distutils/util.py131
-rw-r--r--setuptools/_distutils/version.py28
-rw-r--r--setuptools/_distutils/versionpredicate.py7
62 files changed, 644 insertions, 597 deletions
diff --git a/setuptools/_distutils/__init__.py b/setuptools/_distutils/__init__.py
index 7dac55b6..8fd493b4 100644
--- a/setuptools/_distutils/__init__.py
+++ b/setuptools/_distutils/__init__.py
@@ -9,7 +9,16 @@ used from a setup script as
"""
import sys
+import importlib
__version__ = sys.version[:sys.version.index(' ')]
-local = True
+
+try:
+ # Allow Debian and pkgsrc (only) to customize system
+ # behavior. Ref pypa/distutils#2 and pypa/distutils#16.
+ # This hook is deprecated and no other environments
+ # should use it.
+ importlib.import_module('_distutils_system_mod')
+except ImportError:
+ pass
diff --git a/setuptools/_distutils/_collections.py b/setuptools/_distutils/_collections.py
new file mode 100644
index 00000000..98fce800
--- /dev/null
+++ b/setuptools/_distutils/_collections.py
@@ -0,0 +1,56 @@
+import collections
+import itertools
+
+
+# from jaraco.collections 3.5.1
+class DictStack(list, collections.abc.Mapping):
+ """
+ A stack of dictionaries that behaves as a view on those dictionaries,
+ giving preference to the last.
+
+ >>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
+ >>> stack['a']
+ 2
+ >>> stack['b']
+ 2
+ >>> stack['c']
+ 2
+ >>> len(stack)
+ 3
+ >>> stack.push(dict(a=3))
+ >>> stack['a']
+ 3
+ >>> set(stack.keys()) == set(['a', 'b', 'c'])
+ True
+ >>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
+ True
+ >>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
+ True
+ >>> d = stack.pop()
+ >>> stack['a']
+ 2
+ >>> d = stack.pop()
+ >>> stack['a']
+ 1
+ >>> stack.get('b', None)
+ >>> 'c' in stack
+ True
+ """
+
+ def __iter__(self):
+ dicts = list.__iter__(self)
+ return iter(set(itertools.chain.from_iterable(c.keys() for c in dicts)))
+
+ def __getitem__(self, key):
+ for scope in reversed(tuple(list.__iter__(self))):
+ if key in scope:
+ return scope[key]
+ raise KeyError(key)
+
+ push = list.append
+
+ def __contains__(self, other):
+ return collections.abc.Mapping.__contains__(self, other)
+
+ def __len__(self):
+ return len(list(iter(self)))
diff --git a/setuptools/_distutils/_msvccompiler.py b/setuptools/_distutils/_msvccompiler.py
index b7a06082..f2f801c5 100644
--- a/setuptools/_distutils/_msvccompiler.py
+++ b/setuptools/_distutils/_msvccompiler.py
@@ -203,7 +203,7 @@ class MSVCCompiler(CCompiler) :
def __init__(self, verbose=0, dry_run=0, force=0):
- CCompiler.__init__ (self, verbose, dry_run, force)
+ super().__init__(verbose, dry_run, force)
# target platform (.plat_name is consistent with 'bdist')
self.plat_name = None
self.initialized = False
@@ -527,7 +527,7 @@ class MSVCCompiler(CCompiler) :
return
warnings.warn(
"Fallback spawn triggered. Please update distutils monkeypatch.")
- with unittest.mock.patch('os.environ', env):
+ with unittest.mock.patch.dict('os.environ', env):
bag.value = super().spawn(cmd)
# -- Miscellaneous methods -----------------------------------------
diff --git a/setuptools/_distutils/bcppcompiler.py b/setuptools/_distutils/bcppcompiler.py
index 071fea5d..2eb6d2e9 100644
--- a/setuptools/_distutils/bcppcompiler.py
+++ b/setuptools/_distutils/bcppcompiler.py
@@ -55,7 +55,7 @@ class BCPPCompiler(CCompiler) :
dry_run=0,
force=0):
- CCompiler.__init__ (self, verbose, dry_run, force)
+ super().__init__(verbose, dry_run, force)
# These executables are assumed to all be in the path.
# Borland doesn't seem to use any special registry settings to
diff --git a/setuptools/_distutils/command/bdist_msi.py b/setuptools/_distutils/command/bdist_msi.py
index 0863a188..15259532 100644
--- a/setuptools/_distutils/command/bdist_msi.py
+++ b/setuptools/_distutils/command/bdist_msi.py
@@ -27,7 +27,7 @@ class PyDialog(Dialog):
def __init__(self, *args, **kw):
"""Dialog(database, name, x, y, w, h, attributes, title, first,
default, cancel, bitmap=true)"""
- Dialog.__init__(self, *args)
+ super().__init__(*args)
ruler = self.h - 36
bmwidth = 152*ruler/328
#if kw.get("bitmap", True):
diff --git a/setuptools/_distutils/command/build_ext.py b/setuptools/_distutils/command/build_ext.py
index 22628baf..181671bf 100644
--- a/setuptools/_distutils/command/build_ext.py
+++ b/setuptools/_distutils/command/build_ext.py
@@ -202,9 +202,7 @@ class build_ext(Command):
# Append the source distribution include and library directories,
# this allows distutils on windows to work in the source tree
self.include_dirs.append(os.path.dirname(get_config_h_filename()))
- _sys_home = getattr(sys, '_home', None)
- if _sys_home:
- self.library_dirs.append(_sys_home)
+ self.library_dirs.append(sys.base_exec_prefix)
# Use the .lib files for the correct architecture
if self.plat_name == 'win32':
diff --git a/setuptools/_distutils/command/check.py b/setuptools/_distutils/command/check.py
index ada25006..525540b6 100644
--- a/setuptools/_distutils/command/check.py
+++ b/setuptools/_distutils/command/check.py
@@ -17,7 +17,7 @@ try:
def __init__(self, source, report_level, halt_level, stream=None,
debug=0, encoding='ascii', error_handler='replace'):
self.messages = []
- Reporter.__init__(self, source, report_level, halt_level, stream,
+ super().__init__(source, report_level, halt_level, stream,
debug, encoding, error_handler)
def system_message(self, level, message, *children, **kwargs):
diff --git a/setuptools/_distutils/command/install.py b/setuptools/_distutils/command/install.py
index e98f0491..41c17d8a 100644
--- a/setuptools/_distutils/command/install.py
+++ b/setuptools/_distutils/command/install.py
@@ -4,6 +4,9 @@ Implements the Distutils 'install' command."""
import sys
import os
+import contextlib
+import sysconfig
+import itertools
from distutils import log
from distutils.core import Command
@@ -14,68 +17,69 @@ from distutils.file_util import write_file
from distutils.util import convert_path, subst_vars, change_root
from distutils.util import get_platform
from distutils.errors import DistutilsOptionError
+from .. import _collections
from site import USER_BASE
from site import USER_SITE
HAS_USER_SITE = True
WINDOWS_SCHEME = {
- 'purelib': '$base/Lib/site-packages',
- 'platlib': '$base/Lib/site-packages',
- 'headers': '$base/Include/$dist_name',
- 'scripts': '$base/Scripts',
- 'data' : '$base',
+ 'purelib': '{base}/Lib/site-packages',
+ 'platlib': '{base}/Lib/site-packages',
+ 'headers': '{base}/Include/{dist_name}',
+ 'scripts': '{base}/Scripts',
+ 'data' : '{base}',
}
INSTALL_SCHEMES = {
- 'unix_prefix': {
- 'purelib': '$base/lib/$implementation_lower$py_version_short/site-packages',
- 'platlib': '$platbase/$platlibdir/$implementation_lower$py_version_short/site-packages',
- 'headers': '$base/include/$implementation_lower$py_version_short$abiflags/$dist_name',
- 'scripts': '$base/bin',
- 'data' : '$base',
+ 'posix_prefix': {
+ 'purelib': '{base}/lib/{implementation_lower}{py_version_short}/site-packages',
+ 'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}/site-packages',
+ 'headers': '{base}/include/{implementation_lower}{py_version_short}{abiflags}/{dist_name}',
+ 'scripts': '{base}/bin',
+ 'data' : '{base}',
},
- 'unix_home': {
- 'purelib': '$base/lib/$implementation_lower',
- 'platlib': '$base/$platlibdir/$implementation_lower',
- 'headers': '$base/include/$implementation_lower/$dist_name',
- 'scripts': '$base/bin',
- 'data' : '$base',
+ 'posix_home': {
+ 'purelib': '{base}/lib/{implementation_lower}',
+ 'platlib': '{base}/{platlibdir}/{implementation_lower}',
+ 'headers': '{base}/include/{implementation_lower}/{dist_name}',
+ 'scripts': '{base}/bin',
+ 'data' : '{base}',
},
'nt': WINDOWS_SCHEME,
'pypy': {
- 'purelib': '$base/site-packages',
- 'platlib': '$base/site-packages',
- 'headers': '$base/include/$dist_name',
- 'scripts': '$base/bin',
- 'data' : '$base',
+ 'purelib': '{base}/site-packages',
+ 'platlib': '{base}/site-packages',
+ 'headers': '{base}/include/{dist_name}',
+ 'scripts': '{base}/bin',
+ 'data' : '{base}',
},
'pypy_nt': {
- 'purelib': '$base/site-packages',
- 'platlib': '$base/site-packages',
- 'headers': '$base/include/$dist_name',
- 'scripts': '$base/Scripts',
- 'data' : '$base',
+ 'purelib': '{base}/site-packages',
+ 'platlib': '{base}/site-packages',
+ 'headers': '{base}/include/{dist_name}',
+ 'scripts': '{base}/Scripts',
+ 'data' : '{base}',
},
}
# user site schemes
if HAS_USER_SITE:
INSTALL_SCHEMES['nt_user'] = {
- 'purelib': '$usersite',
- 'platlib': '$usersite',
- 'headers': '$userbase/$implementation$py_version_nodot/Include/$dist_name',
- 'scripts': '$userbase/$implementation$py_version_nodot/Scripts',
- 'data' : '$userbase',
+ 'purelib': '{usersite}',
+ 'platlib': '{usersite}',
+ 'headers': '{userbase}/{implementation}{py_version_nodot_plat}/Include/{dist_name}',
+ 'scripts': '{userbase}/{implementation}{py_version_nodot_plat}/Scripts',
+ 'data' : '{userbase}',
}
- INSTALL_SCHEMES['unix_user'] = {
- 'purelib': '$usersite',
- 'platlib': '$usersite',
+ INSTALL_SCHEMES['posix_user'] = {
+ 'purelib': '{usersite}',
+ 'platlib': '{usersite}',
'headers':
- '$userbase/include/$implementation_lower$py_version_short$abiflags/$dist_name',
- 'scripts': '$userbase/bin',
- 'data' : '$userbase',
+ '{userbase}/include/{implementation_lower}{py_version_short}{abiflags}/{dist_name}',
+ 'scripts': '{userbase}/bin',
+ 'data' : '{userbase}',
}
# The keys to an installation scheme; if any new types of files are to be
@@ -83,6 +87,31 @@ if HAS_USER_SITE:
# and to SCHEME_KEYS here.
SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data')
+
+def _load_sysconfig_schemes():
+ with contextlib.suppress(AttributeError):
+ return {
+ scheme: sysconfig.get_paths(scheme, expand=False)
+ for scheme in sysconfig.get_scheme_names()
+ }
+
+
+def _load_schemes():
+ """
+ Extend default schemes with schemes from sysconfig.
+ """
+
+ sysconfig_schemes = _load_sysconfig_schemes() or {}
+
+ return {
+ scheme: {
+ **INSTALL_SCHEMES.get(scheme, {}),
+ **sysconfig_schemes.get(scheme, {}),
+ }
+ for scheme in set(itertools.chain(INSTALL_SCHEMES, sysconfig_schemes))
+ }
+
+
def _get_implementation():
if hasattr(sys, 'pypy_version_info'):
return 'PyPy'
@@ -90,6 +119,65 @@ def _get_implementation():
return 'Python'
+def _select_scheme(ob, name):
+ scheme = _inject_headers(name, _load_scheme(_resolve_scheme(name)))
+ vars(ob).update(_remove_set(ob, _scheme_attrs(scheme)))
+
+
+def _remove_set(ob, attrs):
+ """
+ Include only attrs that are None in ob.
+ """
+ return {
+ key: value
+ for key, value in attrs.items()
+ if getattr(ob, key) is None
+ }
+
+
+def _resolve_scheme(name):
+ os_name, sep, key = name.partition('_')
+ try:
+ resolved = sysconfig.get_preferred_scheme(key)
+ except Exception:
+ resolved = _pypy_hack(name)
+ return resolved
+
+
+def _load_scheme(name):
+ return _load_schemes()[name]
+
+
+def _inject_headers(name, scheme):
+ """
+ Given a scheme name and the resolved scheme,
+ if the scheme does not include headers, resolve
+ the fallback scheme for the name and use headers
+ from it. pypa/distutils#88
+ """
+ # Bypass the preferred scheme, which may not
+ # have defined headers.
+ fallback = _load_scheme(_pypy_hack(name))
+ scheme.setdefault('headers', fallback['headers'])
+ return scheme
+
+
+def _scheme_attrs(scheme):
+ """Resolve install directories by applying the install schemes."""
+ return {
+ f'install_{key}': scheme[key]
+ for key in SCHEME_KEYS
+ }
+
+
+def _pypy_hack(name):
+ PY37 = sys.version_info < (3, 8)
+ old_pypy = hasattr(sys, 'pypy_version_info') and PY37
+ prefix = not name.endswith(('_user', '_home'))
+ pypy_name = 'pypy' + '_nt' * (os.name == 'nt')
+ return pypy_name if old_pypy and prefix else name
+
+
class install(Command):
description = "install everything from build directory"
@@ -284,7 +372,7 @@ class install(Command):
# input a heady brew of prefix, exec_prefix, home, install_base,
# install_platbase, user-supplied versions of
# install_{purelib,platlib,lib,scripts,data,...}, and the
- # INSTALL_SCHEME dictionary above. Phew!
+ # install schemes. Phew!
self.dump_dirs("pre-finalize_{unix,other}")
@@ -307,25 +395,35 @@ class install(Command):
except AttributeError:
# sys.abiflags may not be defined on all platforms.
abiflags = ''
- self.config_vars = {'dist_name': self.distribution.get_name(),
- 'dist_version': self.distribution.get_version(),
- 'dist_fullname': self.distribution.get_fullname(),
- 'py_version': py_version,
- 'py_version_short': '%d.%d' % sys.version_info[:2],
- 'py_version_nodot': '%d%d' % sys.version_info[:2],
- 'sys_prefix': prefix,
- 'prefix': prefix,
- 'sys_exec_prefix': exec_prefix,
- 'exec_prefix': exec_prefix,
- 'abiflags': abiflags,
- 'platlibdir': getattr(sys, 'platlibdir', 'lib'),
- 'implementation_lower': _get_implementation().lower(),
- 'implementation': _get_implementation(),
- }
+ local_vars = {
+ 'dist_name': self.distribution.get_name(),
+ 'dist_version': self.distribution.get_version(),
+ 'dist_fullname': self.distribution.get_fullname(),
+ 'py_version': py_version,
+ 'py_version_short': '%d.%d' % sys.version_info[:2],
+ 'py_version_nodot': '%d%d' % sys.version_info[:2],
+ 'sys_prefix': prefix,
+ 'prefix': prefix,
+ 'sys_exec_prefix': exec_prefix,
+ 'exec_prefix': exec_prefix,
+ 'abiflags': abiflags,
+ 'platlibdir': getattr(sys, 'platlibdir', 'lib'),
+ 'implementation_lower': _get_implementation().lower(),
+ 'implementation': _get_implementation(),
+ }
+
+ # vars for compatibility on older Pythons
+ compat_vars = dict(
+ # Python 3.9 and earlier
+ py_version_nodot_plat=getattr(sys, 'winver', '').replace('.', ''),
+ )
if HAS_USER_SITE:
- self.config_vars['userbase'] = self.install_userbase
- self.config_vars['usersite'] = self.install_usersite
+ local_vars['userbase'] = self.install_userbase
+ local_vars['usersite'] = self.install_usersite
+
+ self.config_vars = _collections.DictStack(
+ [compat_vars, sysconfig.get_config_vars(), local_vars])
self.expand_basedirs()
@@ -333,13 +431,13 @@ class install(Command):
# Now define config vars for the base directories so we can expand
# everything else.
- self.config_vars['base'] = self.install_base
- self.config_vars['platbase'] = self.install_platbase
+ local_vars['base'] = self.install_base
+ local_vars['platbase'] = self.install_platbase
if DEBUG:
from pprint import pprint
print("config vars:")
- pprint(self.config_vars)
+ pprint(dict(self.config_vars))
# Expand "~" and configuration variables in the installation
# directories.
@@ -415,12 +513,17 @@ class install(Command):
def finalize_unix(self):
"""Finalizes options for posix platforms."""
if self.install_base is not None or self.install_platbase is not None:
- if ((self.install_lib is None and
- self.install_purelib is None and
- self.install_platlib is None) or
+ incomplete_scheme = (
+ (
+ self.install_lib is None and
+ self.install_purelib is None and
+ self.install_platlib is None
+ ) or
self.install_headers is None or
self.install_scripts is None or
- self.install_data is None):
+ self.install_data is None
+ )
+ if incomplete_scheme:
raise DistutilsOptionError(
"install-base or install-platbase supplied, but "
"installation scheme is incomplete")
@@ -431,18 +534,23 @@ class install(Command):
raise DistutilsPlatformError(
"User base directory is not specified")
self.install_base = self.install_platbase = self.install_userbase
- self.select_scheme("unix_user")
+ self.select_scheme("posix_user")
elif self.home is not None:
self.install_base = self.install_platbase = self.home
- self.select_scheme("unix_home")
+ self.select_scheme("posix_home")
else:
if self.prefix is None:
if self.exec_prefix is not None:
raise DistutilsOptionError(
"must not supply exec-prefix without prefix")
- self.prefix = os.path.normpath(sys.prefix)
- self.exec_prefix = os.path.normpath(sys.exec_prefix)
+ # Allow Fedora to add components to the prefix
+ _prefix_addition = getattr(sysconfig, '_prefix_addition', "")
+
+ self.prefix = (
+ os.path.normpath(sys.prefix) + _prefix_addition)
+ self.exec_prefix = (
+ os.path.normpath(sys.exec_prefix) + _prefix_addition)
else:
if self.exec_prefix is None:
@@ -450,7 +558,7 @@ class install(Command):
self.install_base = self.prefix
self.install_platbase = self.exec_prefix
- self.select_scheme("unix_prefix")
+ self.select_scheme("posix_prefix")
def finalize_other(self):
"""Finalizes options for non-posix platforms"""
@@ -462,7 +570,7 @@ class install(Command):
self.select_scheme(os.name + "_user")
elif self.home is not None:
self.install_base = self.install_platbase = self.home
- self.select_scheme("unix_home")
+ self.select_scheme("posix_home")
else:
if self.prefix is None:
self.prefix = os.path.normpath(sys.prefix)
@@ -475,20 +583,7 @@ class install(Command):
"I don't know how to install stuff on '%s'" % os.name)
def select_scheme(self, name):
- """Sets the install directories by applying the install schemes."""
- # it's the caller's problem if they supply a bad name!
- if (hasattr(sys, 'pypy_version_info') and
- sys.version_info < (3, 8) and
- not name.endswith(('_user', '_home'))):
- if os.name == 'nt':
- name = 'pypy_nt'
- else:
- name = 'pypy'
- scheme = INSTALL_SCHEMES[name]
- for key in SCHEME_KEYS:
- attrname = 'install_' + key
- if getattr(self, attrname) is None:
- setattr(self, attrname, scheme[key])
+ _select_scheme(self, name)
def _expand_attrs(self, attrs):
for attr in attrs:
@@ -562,7 +657,7 @@ class install(Command):
return
home = convert_path(os.path.expanduser("~"))
for name, path in self.config_vars.items():
- if path.startswith(home) and not os.path.isdir(path):
+ if str(path).startswith(home) and not os.path.isdir(path):
self.debug_print("os.makedirs('%s', 0o700)" % path)
os.makedirs(path, 0o700)
diff --git a/setuptools/_distutils/command/install_egg_info.py b/setuptools/_distutils/command/install_egg_info.py
index 0ddc7367..adc0323f 100644
--- a/setuptools/_distutils/command/install_egg_info.py
+++ b/setuptools/_distutils/command/install_egg_info.py
@@ -19,14 +19,21 @@ class install_egg_info(Command):
def initialize_options(self):
self.install_dir = None
- def finalize_options(self):
- self.set_undefined_options('install_lib',('install_dir','install_dir'))
- basename = "%s-%s-py%d.%d.egg-info" % (
+ @property
+ def basename(self):
+ """
+ Allow basename to be overridden by child class.
+ Ref pypa/distutils#2.
+ """
+ return "%s-%s-py%d.%d.egg-info" % (
to_filename(safe_name(self.distribution.get_name())),
to_filename(safe_version(self.distribution.get_version())),
*sys.version_info[:2]
)
- self.target = os.path.join(self.install_dir, basename)
+
+ def finalize_options(self):
+ self.set_undefined_options('install_lib',('install_dir','install_dir'))
+ self.target = os.path.join(self.install_dir, self.basename)
self.outputs = [self.target]
def run(self):
diff --git a/setuptools/_distutils/core.py b/setuptools/_distutils/core.py
index d603d4a4..f43888ea 100644
--- a/setuptools/_distutils/core.py
+++ b/setuptools/_distutils/core.py
@@ -8,6 +8,7 @@ really defined in distutils.dist and distutils.cmd.
import os
import sys
+import tokenize
from distutils.debug import DEBUG
from distutils.errors import *
@@ -144,29 +145,41 @@ def setup (**attrs):
# And finally, run all the commands found on the command line.
if ok:
- try:
- dist.run_commands()
- except KeyboardInterrupt:
- raise SystemExit("interrupted")
- except OSError as exc:
- if DEBUG:
- sys.stderr.write("error: %s\n" % (exc,))
- raise
- else:
- raise SystemExit("error: %s" % (exc,))
-
- except (DistutilsError,
- CCompilerError) as msg:
- if DEBUG:
- raise
- else:
- raise SystemExit("error: " + str(msg))
+ return run_commands(dist)
return dist
# setup ()
+def run_commands (dist):
+ """Given a Distribution object run all the commands,
+ raising ``SystemExit`` errors in the case of failure.
+
+ This function assumes that either ``sys.argv`` or ``dist.script_args``
+ is already set accordingly.
+ """
+ try:
+ dist.run_commands()
+ except KeyboardInterrupt:
+ raise SystemExit("interrupted")
+ except OSError as exc:
+ if DEBUG:
+ sys.stderr.write("error: %s\n" % (exc,))
+ raise
+ else:
+ raise SystemExit("error: %s" % (exc,))
+
+ except (DistutilsError,
+ CCompilerError) as msg:
+ if DEBUG:
+ raise
+ else:
+ raise SystemExit("error: " + str(msg))
+
+ return dist
+
+
def run_setup (script_name, script_args=None, stop_after="run"):
"""Run a setup script in a somewhat controlled environment, and
return the Distribution instance that drives things. This is useful
@@ -205,14 +218,16 @@ def run_setup (script_name, script_args=None, stop_after="run"):
_setup_stop_after = stop_after
save_argv = sys.argv.copy()
- g = {'__file__': script_name}
+ g = {'__file__': script_name, '__name__': '__main__'}
try:
try:
sys.argv[0] = script_name
if script_args is not None:
sys.argv[1:] = script_args
- with open(script_name, 'rb') as f:
- exec(f.read(), g)
+ # tokenize.open supports automatic encoding detection
+ with tokenize.open(script_name) as f:
+ code = f.read().replace(r'\r\n', r'\n')
+ exec(code, g)
finally:
sys.argv = save_argv
_setup_stop_after = None
diff --git a/setuptools/_distutils/cygwinccompiler.py b/setuptools/_distutils/cygwinccompiler.py
index f1c38e39..c5c86d8f 100644
--- a/setuptools/_distutils/cygwinccompiler.py
+++ b/setuptools/_distutils/cygwinccompiler.py
@@ -50,15 +50,15 @@ cygwin in no-cygwin mode).
import os
import sys
import copy
-from subprocess import Popen, PIPE, check_output
-import re
+import shlex
+import warnings
+from subprocess import check_output
from distutils.unixccompiler import UnixCCompiler
from distutils.file_util import write_file
from distutils.errors import (DistutilsExecError, CCompilerError,
CompileError, UnknownFileError)
-from distutils.version import LooseVersion
-from distutils.spawn import find_executable
+from distutils.version import LooseVersion, suppress_known_deprecation
def get_msvcr():
"""Include the appropriate MSVC runtime library if Python was built
@@ -82,6 +82,15 @@ def get_msvcr():
elif msc_ver == '1600':
# VS2010 / MSVC 10.0
return ['msvcr100']
+ elif msc_ver == '1700':
+ # VS2012 / MSVC 11.0
+ return ['msvcr110']
+ elif msc_ver == '1800':
+ # VS2013 / MSVC 12.0
+ return ['msvcr120']
+ elif 1900 <= int(msc_ver) < 2000:
+ # VS2015 / MSVC 14.0
+ return ['ucrt', 'vcruntime140']
else:
raise ValueError("Unknown MS Compiler version %s " % msc_ver)
@@ -99,7 +108,7 @@ class CygwinCCompiler(UnixCCompiler):
def __init__(self, verbose=0, dry_run=0, force=0):
- UnixCCompiler.__init__(self, verbose, dry_run, force)
+ super().__init__(verbose, dry_run, force)
status, details = check_config_h()
self.debug_print("Python's GCC status: %s (details: %s)" %
@@ -114,33 +123,8 @@ class CygwinCCompiler(UnixCCompiler):
self.cc = os.environ.get('CC', 'gcc')
self.cxx = os.environ.get('CXX', 'g++')
- if ('gcc' in self.cc): # Start gcc workaround
- self.gcc_version, self.ld_version, self.dllwrap_version = \
- get_versions()
- self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" %
- (self.gcc_version,
- self.ld_version,
- self.dllwrap_version) )
-
- # ld_version >= "2.10.90" and < "2.13" should also be able to use
- # gcc -mdll instead of dllwrap
- # Older dllwraps had own version numbers, newer ones use the
- # same as the rest of binutils ( also ld )
- # dllwrap 2.10.90 is buggy
- if self.ld_version >= "2.10.90":
- self.linker_dll = self.cc
- else:
- self.linker_dll = "dllwrap"
-
- # ld_version >= "2.13" support -shared so use it instead of
- # -mdll -static
- if self.ld_version >= "2.13":
- shared_option = "-shared"
- else:
- shared_option = "-mdll -static"
- else: # Assume linker is up to date
- self.linker_dll = self.cc
- shared_option = "-shared"
+ self.linker_dll = self.cc
+ shared_option = "-shared"
self.set_executables(compiler='%s -mcygwin -O -Wall' % self.cc,
compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc,
@@ -149,17 +133,24 @@ class CygwinCCompiler(UnixCCompiler):
linker_so=('%s -mcygwin %s' %
(self.linker_dll, shared_option)))
- # cygwin and mingw32 need different sets of libraries
- if ('gcc' in self.cc and self.gcc_version == "2.91.57"):
- # cygwin shouldn't need msvcrt, but without the dlls will crash
- # (gcc version 2.91.57) -- perhaps something about initialization
- self.dll_libraries=["msvcrt"]
- self.warn(
- "Consider upgrading to a newer version of gcc")
- else:
- # Include the appropriate MSVC runtime library if Python was built
- # with MSVC 7.0 or later.
- self.dll_libraries = get_msvcr()
+ # Include the appropriate MSVC runtime library if Python was built
+ # with MSVC 7.0 or later.
+ self.dll_libraries = get_msvcr()
+
+ @property
+ def gcc_version(self):
+ # Older numpy dependend on this existing to check for ancient
+ # gcc versions. This doesn't make much sense with clang etc so
+ # just hardcode to something recent.
+ # https://github.com/numpy/numpy/pull/20333
+ warnings.warn(
+ "gcc_version attribute of CygwinCCompiler is deprecated. "
+ "Instead of returning actual gcc version a fixed value 11.2.0 is returned.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ with suppress_known_deprecation():
+ return LooseVersion("11.2.0")
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
"""Compiles the source by spawning GCC and windres if needed."""
@@ -221,24 +212,17 @@ class CygwinCCompiler(UnixCCompiler):
# next add options for def-file and to creating import libraries
- # dllwrap uses different options than gcc/ld
- if self.linker_dll == "dllwrap":
- extra_preargs.extend(["--output-lib", lib_file])
- # for dllwrap we have to use a special option
- extra_preargs.extend(["--def", def_file])
- # we use gcc/ld here and can be sure ld is >= 2.9.10
- else:
- # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
- #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
- # for gcc/ld the def-file is specified as any object files
- objects.append(def_file)
+ # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
+ #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
+ # for gcc/ld the def-file is specified as any object files
+ objects.append(def_file)
#end: if ((export_symbols is not None) and
# (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
# who wants symbols and a many times larger output file
# should explicitly switch the debug mode on
- # otherwise we let dllwrap/ld strip the output file
+ # otherwise we let ld strip the output file
# (On my machine: 10KiB < stripped_file < ??100KiB
# unstripped_file = stripped_file + XXX KiB
# ( XXX=254 for a typical python extension))
@@ -284,21 +268,9 @@ class Mingw32CCompiler(CygwinCCompiler):
def __init__(self, verbose=0, dry_run=0, force=0):
- CygwinCCompiler.__init__ (self, verbose, dry_run, force)
-
- # ld_version >= "2.13" support -shared so use it instead of
- # -mdll -static
- if ('gcc' in self.cc and self.ld_version < "2.13"):
- shared_option = "-mdll -static"
- else:
- shared_option = "-shared"
+ super().__init__ (verbose, dry_run, force)
- # A real mingw32 doesn't need to specify a different entry point,
- # but cygwin 2.91.57 in no-cygwin-mode needs it.
- if ('gcc' in self.cc and self.gcc_version <= "2.91.57"):
- entry_point = '--entry _DllMain@12'
- else:
- entry_point = ''
+ shared_option = "-shared"
if is_cygwincc(self.cc):
raise CCompilerError(
@@ -308,9 +280,9 @@ class Mingw32CCompiler(CygwinCCompiler):
compiler_so='%s -mdll -O -Wall' % self.cc,
compiler_cxx='%s -O -Wall' % self.cxx,
linker_exe='%s' % self.cc,
- linker_so='%s %s %s'
- % (self.linker_dll, shared_option,
- entry_point))
+ linker_so='%s %s'
+ % (self.linker_dll, shared_option))
+
# Maybe we should also append -mthreads, but then the finished
# dlls need another dll (mingwm10.dll see Mingw32 docs)
# (-mthreads: Support thread-safe exception handling on `Mingw32')
@@ -377,38 +349,14 @@ def check_config_h():
return (CONFIG_H_UNCERTAIN,
"couldn't read '%s': %s" % (fn, exc.strerror))
-RE_VERSION = re.compile(br'(\d+\.\d+(\.\d+)*)')
-
-def _find_exe_version(cmd):
- """Find the version of an executable by running `cmd` in the shell.
-
- If the command is not found, or the output does not match
- `RE_VERSION`, returns None.
- """
- executable = cmd.split()[0]
- if find_executable(executable) is None:
- return None
- out = Popen(cmd, shell=True, stdout=PIPE).stdout
- try:
- out_string = out.read()
- finally:
- out.close()
- result = RE_VERSION.search(out_string)
- if result is None:
- return None
- # LooseVersion works with strings
- # so we need to decode our bytes
- return LooseVersion(result.group(1).decode())
-
-def get_versions():
- """ Try to find out the versions of gcc, ld and dllwrap.
-
- If not possible it returns None for it.
- """
- commands = ['gcc -dumpversion', 'ld -v', 'dllwrap --version']
- return tuple([_find_exe_version(cmd) for cmd in commands])
-
def is_cygwincc(cc):
'''Try to determine if the compiler that would be used is from cygwin.'''
- out_string = check_output([cc, '-dumpmachine'])
+ out_string = check_output(shlex.split(cc) + ['-dumpmachine'])
return out_string.strip().endswith(b'cygwin')
+
+
+get_versions = None
+"""
+A stand-in for the previous get_versions() function to prevent failures
+when monkeypatched. See pypa/setuptools#2969.
+"""
diff --git a/setuptools/_distutils/log.py b/setuptools/_distutils/log.py
index 8ef6b28e..a68b156b 100644
--- a/setuptools/_distutils/log.py
+++ b/setuptools/_distutils/log.py
@@ -3,13 +3,14 @@
# The class here is styled after PEP 282 so that it could later be
# replaced with a standard Python logging implementation.
+import sys
+
DEBUG = 1
INFO = 2
WARN = 3
ERROR = 4
FATAL = 5
-import sys
class Log:
@@ -54,6 +55,7 @@ class Log:
def fatal(self, msg, *args):
self._log(FATAL, msg, args)
+
_global_log = Log()
log = _global_log.log
debug = _global_log.debug
@@ -62,12 +64,14 @@ warn = _global_log.warn
error = _global_log.error
fatal = _global_log.fatal
+
def set_threshold(level):
# return the old threshold for use from tests
old = _global_log.threshold
_global_log.threshold = level
return old
+
def set_verbosity(v):
if v <= 0:
set_threshold(WARN)
diff --git a/setuptools/_distutils/msvc9compiler.py b/setuptools/_distutils/msvc9compiler.py
index a1b3b02f..6b627383 100644
--- a/setuptools/_distutils/msvc9compiler.py
+++ b/setuptools/_distutils/msvc9compiler.py
@@ -291,8 +291,6 @@ def query_vcvarsall(version, arch="x86"):
# More globals
VERSION = get_build_version()
-if VERSION < 8.0:
- raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
# MACROS = MacroExpander(VERSION)
class MSVCCompiler(CCompiler) :
@@ -326,7 +324,7 @@ class MSVCCompiler(CCompiler) :
exe_extension = '.exe'
def __init__(self, verbose=0, dry_run=0, force=0):
- CCompiler.__init__ (self, verbose, dry_run, force)
+ super().__init__(verbose, dry_run, force)
self.__version = VERSION
self.__root = r"Software\Microsoft\VisualStudio"
# self.__macros = MACROS
@@ -339,6 +337,8 @@ class MSVCCompiler(CCompiler) :
def initialize(self, plat_name=None):
# multi-init means we would need to check platform same each time...
assert not self.initialized, "don't init multiple times"
+ if self.__version < 8.0:
+ raise DistutilsPlatformError("VC %0.1f is not supported by this module" % self.__version)
if plat_name is None:
plat_name = get_platform()
# sanity check for platforms to prevent obscure errors later.
diff --git a/setuptools/_distutils/msvccompiler.py b/setuptools/_distutils/msvccompiler.py
index 2d447b85..e1367b89 100644
--- a/setuptools/_distutils/msvccompiler.py
+++ b/setuptools/_distutils/msvccompiler.py
@@ -228,7 +228,7 @@ class MSVCCompiler(CCompiler) :
exe_extension = '.exe'
def __init__(self, verbose=0, dry_run=0, force=0):
- CCompiler.__init__ (self, verbose, dry_run, force)
+ super().__init__(verbose, dry_run, force)
self.__version = get_build_version()
self.__arch = get_build_architecture()
if self.__arch == "Intel":
diff --git a/setuptools/_distutils/spawn.py b/setuptools/_distutils/spawn.py
index 6e1c89f1..b2d10e39 100644
--- a/setuptools/_distutils/spawn.py
+++ b/setuptools/_distutils/spawn.py
@@ -10,7 +10,7 @@ import sys
import os
import subprocess
-from distutils.errors import DistutilsPlatformError, DistutilsExecError
+from distutils.errors import DistutilsExecError
from distutils.debug import DEBUG
from distutils import log
diff --git a/setuptools/_distutils/sysconfig.py b/setuptools/_distutils/sysconfig.py
index 8832b3ec..4a77a431 100644
--- a/setuptools/_distutils/sysconfig.py
+++ b/setuptools/_distutils/sysconfig.py
@@ -13,6 +13,7 @@ import _imp
import os
import re
import sys
+import sysconfig
from .errors import DistutilsPlatformError
@@ -129,6 +130,14 @@ def get_python_inc(plat_specific=0, prefix=None):
"on platform '%s'" % os.name)
+# allow this behavior to be monkey-patched. Ref pypa/distutils#2.
+def _posix_lib(standard_lib, libpython, early_prefix, prefix):
+ if standard_lib:
+ return libpython
+ else:
+ return os.path.join(libpython, "site-packages")
+
+
def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
"""Return the directory containing the Python library (standard or
site additions).
@@ -152,6 +161,8 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
return os.path.join(prefix, "lib-python", sys.version[0])
return os.path.join(prefix, 'site-packages')
+ early_prefix = prefix
+
if prefix is None:
if standard_lib:
prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
@@ -169,10 +180,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
implementation = 'pypy' if IS_PYPY else 'python'
libpython = os.path.join(prefix, libdir,
implementation + get_python_version())
- if standard_lib:
- return libpython
- else:
- return os.path.join(libpython, "site-packages")
+ return _posix_lib(standard_lib, libpython, early_prefix, prefix)
elif os.name == "nt":
if standard_lib:
return os.path.join(prefix, "Lib")
@@ -267,21 +275,15 @@ def get_config_h_filename():
inc_dir = os.path.join(_sys_home or project_base, "PC")
else:
inc_dir = _sys_home or project_base
+ return os.path.join(inc_dir, 'pyconfig.h')
else:
- inc_dir = get_python_inc(plat_specific=1)
+ return sysconfig.get_config_h_filename()
- return os.path.join(inc_dir, 'pyconfig.h')
def get_makefile_filename():
"""Return full pathname of installed Makefile from the Python build."""
- if python_build:
- return os.path.join(_sys_home or project_base, "Makefile")
- lib_dir = get_python_lib(plat_specific=0, standard_lib=1)
- config_file = 'config-{}{}'.format(get_python_version(), build_flags)
- if hasattr(sys.implementation, '_multiarch'):
- config_file += '-%s' % sys.implementation._multiarch
- return os.path.join(lib_dir, config_file, 'Makefile')
+ return sysconfig.get_makefile_filename()
def parse_config_h(fp, g=None):
@@ -291,26 +293,7 @@ def parse_config_h(fp, g=None):
optional dictionary is passed in as the second argument, it is
used instead of a new dictionary.
"""
- if g is None:
- g = {}
- define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
- undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
- #
- while True:
- line = fp.readline()
- if not line:
- break
- m = define_rx.match(line)
- if m:
- n, v = m.group(1, 2)
- try: v = int(v)
- except ValueError: pass
- g[n] = v
- else:
- m = undef_rx.match(line)
- if m:
- g[m.group(1)] = 0
- return g
+ return sysconfig.parse_config_h(fp, vars=g)
# Regexes needed for parsing Makefile (and similar syntaxes,
@@ -452,15 +435,21 @@ def expand_makefile_vars(s, vars):
_config_vars = None
+
+_sysconfig_name_tmpl = '_sysconfigdata_{abi}_{platform}_{multiarch}'
+
+
def _init_posix():
"""Initialize the module as appropriate for POSIX systems."""
# _sysconfigdata is generated at build time, see the sysconfig module
- name = os.environ.get('_PYTHON_SYSCONFIGDATA_NAME',
- '_sysconfigdata_{abi}_{platform}_{multiarch}'.format(
- abi=sys.abiflags,
- platform=sys.platform,
- multiarch=getattr(sys.implementation, '_multiarch', ''),
- ))
+ name = os.environ.get(
+ '_PYTHON_SYSCONFIGDATA_NAME',
+ _sysconfig_name_tmpl.format(
+ abi=sys.abiflags,
+ platform=sys.platform,
+ multiarch=getattr(sys.implementation, '_multiarch', ''),
+ ),
+ )
try:
_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
except ImportError:
diff --git a/setuptools/_distutils/tests/py38compat.py b/setuptools/_distutils/tests/py38compat.py
index 32269c7b..c949f58e 100644
--- a/setuptools/_distutils/tests/py38compat.py
+++ b/setuptools/_distutils/tests/py38compat.py
@@ -2,6 +2,11 @@
import contextlib
import builtins
+import sys
+
+from test.support import requires_zlib
+import test.support
+
ModuleNotFoundError = getattr(builtins, 'ModuleNotFoundError', ImportError)
@@ -51,3 +56,7 @@ try:
from test.support.warnings_helper import save_restore_warnings_filters
except (ModuleNotFoundError, ImportError):
save_restore_warnings_filters = _save_restore_warnings_filters
+
+
+if sys.version_info < (3, 9):
+ requires_zlib = lambda: test.support.requires_zlib
diff --git a/setuptools/_distutils/tests/test_archive_util.py b/setuptools/_distutils/tests/test_archive_util.py
index ce6456dc..800b9018 100644
--- a/setuptools/_distutils/tests/test_archive_util.py
+++ b/setuptools/_distutils/tests/test_archive_util.py
@@ -14,16 +14,11 @@ from distutils.archive_util import (check_archive_formats, make_tarball,
from distutils.spawn import find_executable, spawn
from distutils.tests import support
from test.support import run_unittest, 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
-try:
- import grp
- import pwd
- UID_GID_SUPPORT = True
-except ImportError:
- UID_GID_SUPPORT = False
try:
import zipfile
@@ -339,7 +334,7 @@ class ArchiveUtilTestCase(support.TempdirManager,
def test_make_archive_owner_group(self):
# testing make_archive with owner and group, with various combinations
# this works even if there's not gid/uid support
- if UID_GID_SUPPORT:
+ if UID_0_SUPPORT:
group = grp.getgrgid(0)[0]
owner = pwd.getpwuid(0)[0]
else:
@@ -364,7 +359,8 @@ class ArchiveUtilTestCase(support.TempdirManager,
self.assertTrue(os.path.exists(res))
@unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib")
- @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ @require_unix_id
+ @require_uid_0
def test_tarfile_root_owner(self):
tmpdir = self._create_files()
base_name = os.path.join(self.mkdtemp(), 'archive')
@@ -391,7 +387,7 @@ class ArchiveUtilTestCase(support.TempdirManager,
archive.close()
def test_suite():
- return unittest.makeSuite(ArchiveUtilTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(ArchiveUtilTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_bdist.py b/setuptools/_distutils/tests/test_bdist.py
index 130d8bf1..8b7498e3 100644
--- a/setuptools/_distutils/tests/test_bdist.py
+++ b/setuptools/_distutils/tests/test_bdist.py
@@ -51,7 +51,7 @@ class BuildTestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(BuildTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildTestCase)
if __name__ == '__main__':
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_bdist_dumb.py b/setuptools/_distutils/tests/test_bdist_dumb.py
index 01a233bc..bb860c8a 100644
--- a/setuptools/_distutils/tests/test_bdist_dumb.py
+++ b/setuptools/_distutils/tests/test_bdist_dumb.py
@@ -91,7 +91,7 @@ class BuildDumbTestCase(support.TempdirManager,
self.assertEqual(contents, sorted(wanted))
def test_suite():
- return unittest.makeSuite(BuildDumbTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildDumbTestCase)
if __name__ == '__main__':
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_bdist_msi.py b/setuptools/_distutils/tests/test_bdist_msi.py
index 937266f8..b1831ef2 100644
--- a/setuptools/_distutils/tests/test_bdist_msi.py
+++ b/setuptools/_distutils/tests/test_bdist_msi.py
@@ -22,7 +22,7 @@ class BDistMSITestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(BDistMSITestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BDistMSITestCase)
if __name__ == '__main__':
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_bdist_rpm.py b/setuptools/_distutils/tests/test_bdist_rpm.py
index 6453a02b..08a7cb46 100644
--- a/setuptools/_distutils/tests/test_bdist_rpm.py
+++ b/setuptools/_distutils/tests/test_bdist_rpm.py
@@ -3,13 +3,16 @@
import unittest
import sys
import os
-from test.support import run_unittest, requires_zlib
+from test.support import run_unittest
from distutils.core import Distribution
from distutils.command.bdist_rpm import bdist_rpm
from distutils.tests import support
from distutils.spawn import find_executable
+from .py38compat import requires_zlib
+
+
SETUP_PY = """\
from distutils.core import setup
import foo
@@ -44,7 +47,7 @@ class BuildRpmTestCase(support.TempdirManager,
# spurious sdtout/stderr output under Mac OS X
@unittest.skipUnless(sys.platform.startswith('linux'),
'spurious sdtout/stderr output under Mac OS X')
- @requires_zlib
+ @requires_zlib()
@unittest.skipIf(find_executable('rpm') is None,
'the rpm command is not found')
@unittest.skipIf(find_executable('rpmbuild') is None,
@@ -87,7 +90,7 @@ class BuildRpmTestCase(support.TempdirManager,
# spurious sdtout/stderr output under Mac OS X
@unittest.skipUnless(sys.platform.startswith('linux'),
'spurious sdtout/stderr output under Mac OS X')
- @requires_zlib
+ @requires_zlib()
# http://bugs.python.org/issue1533164
@unittest.skipIf(find_executable('rpm') is None,
'the rpm command is not found')
@@ -129,7 +132,7 @@ class BuildRpmTestCase(support.TempdirManager,
os.remove(os.path.join(pkg_dir, 'dist', 'foo-0.1-1.noarch.rpm'))
def test_suite():
- return unittest.makeSuite(BuildRpmTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildRpmTestCase)
if __name__ == '__main__':
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_bdist_wininst.py b/setuptools/_distutils/tests/test_bdist_wininst.py
index 31cf2628..59f25167 100644
--- a/setuptools/_distutils/tests/test_bdist_wininst.py
+++ b/setuptools/_distutils/tests/test_bdist_wininst.py
@@ -34,7 +34,7 @@ class BuildWinInstTestCase(support.TempdirManager,
self.assertGreater(len(exe_file), 10)
def test_suite():
- return unittest.makeSuite(BuildWinInstTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildWinInstTestCase)
if __name__ == '__main__':
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_build.py b/setuptools/_distutils/tests/test_build.py
index b020a5ba..83a9e4f4 100644
--- a/setuptools/_distutils/tests/test_build.py
+++ b/setuptools/_distutils/tests/test_build.py
@@ -50,7 +50,7 @@ class BuildTestCase(support.TempdirManager,
self.assertEqual(cmd.executable, os.path.normpath(sys.executable))
def test_suite():
- return unittest.makeSuite(BuildTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_build_clib.py b/setuptools/_distutils/tests/test_build_clib.py
index 259c4352..d50ead7c 100644
--- a/setuptools/_distutils/tests/test_build_clib.py
+++ b/setuptools/_distutils/tests/test_build_clib.py
@@ -130,7 +130,7 @@ class BuildCLibTestCase(support.TempdirManager,
self.assertIn('libfoo.a', os.listdir(build_temp))
def test_suite():
- return unittest.makeSuite(BuildCLibTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildCLibTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_build_ext.py b/setuptools/_distutils/tests/test_build_ext.py
index 85ecf4b7..920e4dc8 100644
--- a/setuptools/_distutils/tests/test_build_ext.py
+++ b/setuptools/_distutils/tests/test_build_ext.py
@@ -493,12 +493,16 @@ class BuildExtTestCase(TempdirManager,
# format the target value as defined in the Apple
# Availability Macros. We can't use the macro names since
# at least one value we test with will not exist yet.
- if target[1] < 10:
+ if target[:2] < (10, 10):
# for 10.1 through 10.9.x -> "10n0"
target = '%02d%01d0' % target
else:
# for 10.10 and beyond -> "10nn00"
- target = '%02d%02d00' % target
+ if len(target) >= 2:
+ target = '%02d%02d00' % target
+ else:
+ # 11 and later can have no minor version (11 instead of 11.0)
+ target = '%02d0000' % target
deptarget_ext = Extension(
'deptarget',
[deptarget_c],
@@ -538,8 +542,8 @@ class ParallelBuildExtTestCase(BuildExtTestCase):
def test_suite():
suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(BuildExtTestCase))
- suite.addTest(unittest.makeSuite(ParallelBuildExtTestCase))
+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(BuildExtTestCase))
+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(ParallelBuildExtTestCase))
return suite
if __name__ == '__main__':
diff --git a/setuptools/_distutils/tests/test_build_py.py b/setuptools/_distutils/tests/test_build_py.py
index 0712e92c..a590a485 100644
--- a/setuptools/_distutils/tests/test_build_py.py
+++ b/setuptools/_distutils/tests/test_build_py.py
@@ -173,7 +173,7 @@ class BuildPyTestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(BuildPyTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildPyTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_build_scripts.py b/setuptools/_distutils/tests/test_build_scripts.py
index 954fc763..f299e51e 100644
--- a/setuptools/_distutils/tests/test_build_scripts.py
+++ b/setuptools/_distutils/tests/test_build_scripts.py
@@ -106,7 +106,7 @@ class BuildScriptsTestCase(support.TempdirManager,
self.assertIn(name, built)
def test_suite():
- return unittest.makeSuite(BuildScriptsTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(BuildScriptsTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_check.py b/setuptools/_distutils/tests/test_check.py
index e534aca1..91bcdceb 100644
--- a/setuptools/_distutils/tests/test_check.py
+++ b/setuptools/_distutils/tests/test_check.py
@@ -157,7 +157,7 @@ class CheckTestCase(support.LoggingSilencer,
'restructuredtext': 1})
def test_suite():
- return unittest.makeSuite(CheckTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(CheckTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_clean.py b/setuptools/_distutils/tests/test_clean.py
index c605afd8..92367499 100644
--- a/setuptools/_distutils/tests/test_clean.py
+++ b/setuptools/_distutils/tests/test_clean.py
@@ -43,7 +43,7 @@ class cleanTestCase(support.TempdirManager,
cmd.run()
def test_suite():
- return unittest.makeSuite(cleanTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(cleanTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_cmd.py b/setuptools/_distutils/tests/test_cmd.py
index cf5197c3..2319214a 100644
--- a/setuptools/_distutils/tests/test_cmd.py
+++ b/setuptools/_distutils/tests/test_cmd.py
@@ -120,7 +120,7 @@ class CommandTestCase(unittest.TestCase):
debug.DEBUG = False
def test_suite():
- return unittest.makeSuite(CommandTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(CommandTestCase)
if __name__ == '__main__':
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_config.py b/setuptools/_distutils/tests/test_config.py
index 344084af..27bd9d44 100644
--- a/setuptools/_distutils/tests/test_config.py
+++ b/setuptools/_distutils/tests/test_config.py
@@ -66,7 +66,7 @@ class BasePyPIRCCommandTestCase(support.TempdirManager,
class command(PyPIRCCommand):
def __init__(self, dist):
- PyPIRCCommand.__init__(self, dist)
+ super().__init__(dist)
def initialize_options(self):
pass
finalize_options = initialize_options
@@ -135,7 +135,7 @@ class PyPIRCCommandTestCase(BasePyPIRCCommandTestCase):
def test_suite():
- return unittest.makeSuite(PyPIRCCommandTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(PyPIRCCommandTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_config_cmd.py b/setuptools/_distutils/tests/test_config_cmd.py
index 4cd9a6b9..2c84719a 100644
--- a/setuptools/_distutils/tests/test_config_cmd.py
+++ b/setuptools/_distutils/tests/test_config_cmd.py
@@ -92,7 +92,7 @@ class ConfigTestCase(support.LoggingSilencer,
self.assertFalse(os.path.exists(f))
def test_suite():
- return unittest.makeSuite(ConfigTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(ConfigTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_core.py b/setuptools/_distutils/tests/test_core.py
index 666ff4a3..7270d699 100644
--- a/setuptools/_distutils/tests/test_core.py
+++ b/setuptools/_distutils/tests/test_core.py
@@ -10,6 +10,7 @@ from . import py38compat as os_helper
import unittest
from distutils.tests import support
from distutils import log
+from distutils.dist import Distribution
# setup script that uses __file__
setup_using___file__ = """\
@@ -45,6 +46,16 @@ class install(_install):
setup(cmdclass={'install': install})
"""
+setup_within_if_main = """\
+from distutils.core import setup
+
+def main():
+ return setup(name="setup_within_if_main")
+
+if __name__ == "__main__":
+ main()
+"""
+
class CoreTestCase(support.EnvironGuard, unittest.TestCase):
def setUp(self):
@@ -115,6 +126,20 @@ class CoreTestCase(support.EnvironGuard, unittest.TestCase):
output = output[:-1]
self.assertEqual(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")
+ self.assertIsInstance(dist, Distribution)
+ self.assertEqual(dist.get_name(), "setup_within_if_main")
+
+ def test_run_commands(self):
+ sys.argv = ['setup.py', 'build']
+ dist = distutils.core.run_setup(
+ self.write_setup(setup_within_if_main), stop_after="commandline")
+ self.assertNotIn('build', dist.have_run)
+ distutils.core.run_commands(dist)
+ self.assertIn('build', dist.have_run)
+
def test_debug_mode(self):
# this covers the code called when DEBUG is set
sys.argv = ['setup.py', '--name']
@@ -134,7 +159,7 @@ class CoreTestCase(support.EnvironGuard, unittest.TestCase):
self.assertEqual(stdout.readlines()[0], wanted)
def test_suite():
- return unittest.makeSuite(CoreTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(CoreTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_cygwinccompiler.py b/setuptools/_distutils/tests/test_cygwinccompiler.py
index 9dc869de..8715a535 100644
--- a/setuptools/_distutils/tests/test_cygwinccompiler.py
+++ b/setuptools/_distutils/tests/test_cygwinccompiler.py
@@ -2,28 +2,14 @@
import unittest
import sys
import os
-from io import BytesIO
from test.support import run_unittest
-from distutils import cygwinccompiler
from distutils.cygwinccompiler import (check_config_h,
CONFIG_H_OK, CONFIG_H_NOTOK,
- CONFIG_H_UNCERTAIN, get_versions,
+ CONFIG_H_UNCERTAIN,
get_msvcr)
from distutils.tests import support
-class FakePopen(object):
- test_class = None
-
- def __init__(self, cmd, shell, stdout):
- self.cmd = cmd.split()[0]
- exes = self.test_class._exes
- if self.cmd in exes:
- # issue #6438 in Python 3.x, Popen returns bytes
- self.stdout = BytesIO(exes[self.cmd])
- else:
- self.stdout = os.popen(cmd, 'r')
-
class CygwinCCompilerTestCase(support.TempdirManager,
unittest.TestCase):
@@ -35,29 +21,16 @@ class CygwinCCompilerTestCase(support.TempdirManager,
from distutils import sysconfig
self.old_get_config_h_filename = sysconfig.get_config_h_filename
sysconfig.get_config_h_filename = self._get_config_h_filename
- self.old_find_executable = cygwinccompiler.find_executable
- cygwinccompiler.find_executable = self._find_executable
- self._exes = {}
- self.old_popen = cygwinccompiler.Popen
- FakePopen.test_class = self
- cygwinccompiler.Popen = FakePopen
def tearDown(self):
sys.version = self.version
from distutils import sysconfig
sysconfig.get_config_h_filename = self.old_get_config_h_filename
- cygwinccompiler.find_executable = self.old_find_executable
- cygwinccompiler.Popen = self.old_popen
super(CygwinCCompilerTestCase, self).tearDown()
def _get_config_h_filename(self):
return self.python_h
- def _find_executable(self, name):
- if name in self._exes:
- return name
- return None
-
def test_check_config_h(self):
# check_config_h looks for "GCC" in sys.version first
@@ -81,40 +54,6 @@ class CygwinCCompilerTestCase(support.TempdirManager,
self.write_file(self.python_h, 'xxx __GNUC__ xxx')
self.assertEqual(check_config_h()[0], CONFIG_H_OK)
- def test_get_versions(self):
-
- # get_versions calls distutils.spawn.find_executable on
- # 'gcc', 'ld' and 'dllwrap'
- self.assertEqual(get_versions(), (None, None, None))
-
- # Let's fake we have 'gcc' and it returns '3.4.5'
- self._exes['gcc'] = b'gcc (GCC) 3.4.5 (mingw special)\nFSF'
- res = get_versions()
- self.assertEqual(str(res[0]), '3.4.5')
-
- # and let's see what happens when the version
- # doesn't match the regular expression
- # (\d+\.\d+(\.\d+)*)
- self._exes['gcc'] = b'very strange output'
- res = get_versions()
- self.assertEqual(res[0], None)
-
- # same thing for ld
- self._exes['ld'] = b'GNU ld version 2.17.50 20060824'
- res = get_versions()
- self.assertEqual(str(res[1]), '2.17.50')
- self._exes['ld'] = b'@(#)PROGRAM:ld PROJECT:ld64-77'
- res = get_versions()
- self.assertEqual(res[1], None)
-
- # and dllwrap
- self._exes['dllwrap'] = b'GNU dllwrap 2.17.50 20060824\nFSF'
- res = get_versions()
- self.assertEqual(str(res[2]), '2.17.50')
- self._exes['dllwrap'] = b'Cheese Wrap'
- res = get_versions()
- self.assertEqual(res[2], None)
-
def test_get_msvcr(self):
# none
@@ -141,14 +80,17 @@ class CygwinCCompilerTestCase(support.TempdirManager,
sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) '
'[MSC v.1500 32 bits (Intel)]')
self.assertEqual(get_msvcr(), ['msvcr90'])
+
+ sys.version = '3.10.0 (tags/v3.10.0:b494f59, Oct 4 2021, 18:46:30) [MSC v.1929 32 bit (Intel)]'
+ self.assertEqual(get_msvcr(), ['ucrt', 'vcruntime140'])
# unknown
sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) '
- '[MSC v.1999 32 bits (Intel)]')
+ '[MSC v.2000 32 bits (Intel)]')
self.assertRaises(ValueError, get_msvcr)
def test_suite():
- return unittest.makeSuite(CygwinCCompilerTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(CygwinCCompilerTestCase)
if __name__ == '__main__':
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_dep_util.py b/setuptools/_distutils/tests/test_dep_util.py
index c6fae39c..0d52740a 100644
--- a/setuptools/_distutils/tests/test_dep_util.py
+++ b/setuptools/_distutils/tests/test_dep_util.py
@@ -74,7 +74,7 @@ class DepUtilTestCase(support.TempdirManager, unittest.TestCase):
def test_suite():
- return unittest.makeSuite(DepUtilTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(DepUtilTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_dir_util.py b/setuptools/_distutils/tests/test_dir_util.py
index d436cf83..1b1f3bbb 100644
--- a/setuptools/_distutils/tests/test_dir_util.py
+++ b/setuptools/_distutils/tests/test_dir_util.py
@@ -133,7 +133,7 @@ class DirUtilTestCase(support.TempdirManager, unittest.TestCase):
def test_suite():
- return unittest.makeSuite(DirUtilTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(DirUtilTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_dist.py b/setuptools/_distutils/tests/test_dist.py
index 45eadee8..36155be1 100644
--- a/setuptools/_distutils/tests/test_dist.py
+++ b/setuptools/_distutils/tests/test_dist.py
@@ -525,8 +525,8 @@ class MetadataTestCase(support.TempdirManager, support.EnvironGuard,
def test_suite():
suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(DistributionTestCase))
- suite.addTest(unittest.makeSuite(MetadataTestCase))
+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(DistributionTestCase))
+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(MetadataTestCase))
return suite
if __name__ == "__main__":
diff --git a/setuptools/_distutils/tests/test_extension.py b/setuptools/_distutils/tests/test_extension.py
index 2eb5b422..78a55daa 100644
--- a/setuptools/_distutils/tests/test_extension.py
+++ b/setuptools/_distutils/tests/test_extension.py
@@ -65,7 +65,7 @@ class ExtensionTestCase(unittest.TestCase):
"Unknown Extension options: 'chic'")
def test_suite():
- return unittest.makeSuite(ExtensionTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(ExtensionTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_file_util.py b/setuptools/_distutils/tests/test_file_util.py
index d2536075..81b90d6c 100644
--- a/setuptools/_distutils/tests/test_file_util.py
+++ b/setuptools/_distutils/tests/test_file_util.py
@@ -118,7 +118,7 @@ class FileUtilTestCase(support.TempdirManager, unittest.TestCase):
def test_suite():
- return unittest.makeSuite(FileUtilTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(FileUtilTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_filelist.py b/setuptools/_distutils/tests/test_filelist.py
index 9ec507b5..a90edcf1 100644
--- a/setuptools/_distutils/tests/test_filelist.py
+++ b/setuptools/_distutils/tests/test_filelist.py
@@ -344,8 +344,8 @@ class FindAllTestCase(unittest.TestCase):
def test_suite():
return unittest.TestSuite([
- unittest.makeSuite(FileListTestCase),
- unittest.makeSuite(FindAllTestCase),
+ unittest.TestLoader().loadTestsFromTestCase(FileListTestCase),
+ unittest.TestLoader().loadTestsFromTestCase(FindAllTestCase),
])
diff --git a/setuptools/_distutils/tests/test_install.py b/setuptools/_distutils/tests/test_install.py
index eb684a09..5dbc06b0 100644
--- a/setuptools/_distutils/tests/test_install.py
+++ b/setuptools/_distutils/tests/test_install.py
@@ -81,7 +81,9 @@ class InstallTestCase(support.TempdirManager,
install_module.USER_SITE = self.user_site
def _expanduser(path):
- return self.tmpdir
+ if path.startswith('~'):
+ return os.path.normpath(self.tmpdir + path[1:])
+ return path
self.old_expand = os.path.expanduser
os.path.expanduser = _expanduser
@@ -94,7 +96,7 @@ class InstallTestCase(support.TempdirManager,
self.addCleanup(cleanup)
- for key in ('nt_user', 'unix_user'):
+ for key in ('nt_user', 'posix_user'):
self.assertIn(key, INSTALL_SCHEMES)
dist = Distribution({'name': 'xx'})
@@ -122,6 +124,17 @@ class InstallTestCase(support.TempdirManager,
self.assertIn('userbase', cmd.config_vars)
self.assertIn('usersite', cmd.config_vars)
+ actual_headers = os.path.relpath(cmd.install_headers, self.user_base)
+ if os.name == 'nt':
+ site_path = os.path.relpath(
+ os.path.dirname(self.old_user_site), self.old_user_base)
+ include = os.path.join(site_path, 'Include')
+ else:
+ include = sysconfig.get_python_inc(0, '')
+ expect_headers = os.path.join(include, 'xx')
+
+ self.assertEqual(os.path.normcase(actual_headers), os.path.normcase(expect_headers))
+
def test_handle_extra_path(self):
dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'})
cmd = install(dist)
@@ -244,7 +257,7 @@ class InstallTestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(InstallTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(InstallTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_install_data.py b/setuptools/_distutils/tests/test_install_data.py
index 32ab296a..6191d2fa 100644
--- a/setuptools/_distutils/tests/test_install_data.py
+++ b/setuptools/_distutils/tests/test_install_data.py
@@ -69,7 +69,7 @@ class InstallDataTestCase(support.TempdirManager,
self.assertTrue(os.path.exists(os.path.join(inst, rone)))
def test_suite():
- return unittest.makeSuite(InstallDataTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(InstallDataTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_install_headers.py b/setuptools/_distutils/tests/test_install_headers.py
index 2217b321..1aa4d09c 100644
--- a/setuptools/_distutils/tests/test_install_headers.py
+++ b/setuptools/_distutils/tests/test_install_headers.py
@@ -33,7 +33,7 @@ class InstallHeadersTestCase(support.TempdirManager,
self.assertEqual(len(cmd.get_outputs()), 2)
def test_suite():
- return unittest.makeSuite(InstallHeadersTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(InstallHeadersTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_install_lib.py b/setuptools/_distutils/tests/test_install_lib.py
index fda6315b..652653f2 100644
--- a/setuptools/_distutils/tests/test_install_lib.py
+++ b/setuptools/_distutils/tests/test_install_lib.py
@@ -109,7 +109,7 @@ class InstallLibTestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(InstallLibTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(InstallLibTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_install_scripts.py b/setuptools/_distutils/tests/test_install_scripts.py
index 1f7b1038..648db3b1 100644
--- a/setuptools/_distutils/tests/test_install_scripts.py
+++ b/setuptools/_distutils/tests/test_install_scripts.py
@@ -76,7 +76,7 @@ class InstallScriptsTestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(InstallScriptsTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(InstallScriptsTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_log.py b/setuptools/_distutils/tests/test_log.py
index 75cf9006..ec2ae028 100644
--- a/setuptools/_distutils/tests/test_log.py
+++ b/setuptools/_distutils/tests/test_log.py
@@ -40,7 +40,7 @@ class TestLog(unittest.TestCase):
'Fαtal\t\\xc8rr\\u014dr')
def test_suite():
- return unittest.makeSuite(TestLog)
+ return unittest.TestLoader().loadTestsFromTestCase(TestLog)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_msvc9compiler.py b/setuptools/_distutils/tests/test_msvc9compiler.py
index 77a07ef3..6235405e 100644
--- a/setuptools/_distutils/tests/test_msvc9compiler.py
+++ b/setuptools/_distutils/tests/test_msvc9compiler.py
@@ -178,7 +178,7 @@ class msvc9compilerTestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(msvc9compilerTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(msvc9compilerTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_msvccompiler.py b/setuptools/_distutils/tests/test_msvccompiler.py
index 46a51cd0..846e5bb8 100644
--- a/setuptools/_distutils/tests/test_msvccompiler.py
+++ b/setuptools/_distutils/tests/test_msvccompiler.py
@@ -98,7 +98,7 @@ class TestSpawn(unittest.TestCase):
compiler = _msvccompiler.MSVCCompiler()
compiler._paths = "expected"
inner_cmd = 'import os; assert os.environ["PATH"] == "expected"'
- command = ['python', '-c', inner_cmd]
+ command = [sys.executable, '-c', inner_cmd]
threads = [
CheckThread(target=compiler.spawn, args=[command])
@@ -132,7 +132,7 @@ class TestSpawn(unittest.TestCase):
def test_suite():
- return unittest.makeSuite(msvccompilerTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(msvccompilerTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_register.py b/setuptools/_distutils/tests/test_register.py
index 84607f99..5770ed58 100644
--- a/setuptools/_distutils/tests/test_register.py
+++ b/setuptools/_distutils/tests/test_register.py
@@ -319,7 +319,7 @@ class RegisterTestCase(BasePyPIRCCommandTestCase):
def test_suite():
- return unittest.makeSuite(RegisterTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(RegisterTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_sdist.py b/setuptools/_distutils/tests/test_sdist.py
index b087a817..4c51717c 100644
--- a/setuptools/_distutils/tests/test_sdist.py
+++ b/setuptools/_distutils/tests/test_sdist.py
@@ -7,6 +7,7 @@ import zipfile
from os.path import join
from textwrap import dedent
from test.support import captured_stdout, run_unittest
+from .unix_compat import require_unix_id, require_uid_0, pwd, grp
from .py38compat import check_warnings
@@ -16,13 +17,6 @@ try:
except ImportError:
ZLIB_SUPPORT = False
-try:
- import grp
- import pwd
- UID_GID_SUPPORT = True
-except ImportError:
- UID_GID_SUPPORT = False
-
from distutils.command.sdist import sdist, show_formats
from distutils.core import Distribution
from distutils.tests.test_config import BasePyPIRCCommandTestCase
@@ -440,7 +434,8 @@ class SDistTestCase(BasePyPIRCCommandTestCase):
'fake-1.0/README.manual'])
@unittest.skipUnless(ZLIB_SUPPORT, "requires zlib")
- @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ @require_unix_id
+ @require_uid_0
@unittest.skipIf(find_executable('tar') is None,
"The tar command is not found")
@unittest.skipIf(find_executable('gzip') is None,
@@ -488,7 +483,7 @@ class SDistTestCase(BasePyPIRCCommandTestCase):
archive.close()
def test_suite():
- return unittest.makeSuite(SDistTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(SDistTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_spawn.py b/setuptools/_distutils/tests/test_spawn.py
index f620da78..c5ed8e2b 100644
--- a/setuptools/_distutils/tests/test_spawn.py
+++ b/setuptools/_distutils/tests/test_spawn.py
@@ -133,7 +133,7 @@ class SpawnTestCase(support.TempdirManager,
def test_suite():
- return unittest.makeSuite(SpawnTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(SpawnTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_sysconfig.py b/setuptools/_distutils/tests/test_sysconfig.py
index 80cd1599..9de3cb70 100644
--- a/setuptools/_distutils/tests/test_sysconfig.py
+++ b/setuptools/_distutils/tests/test_sysconfig.py
@@ -38,6 +38,12 @@ class SysconfigTestCase(support.EnvironGuard, unittest.TestCase):
config_h = sysconfig.get_config_h_filename()
self.assertTrue(os.path.isfile(config_h), config_h)
+ @unittest.skipIf(sys.platform == 'win32',
+ 'Makefile only exists on Unix like systems')
+ def test_get_makefile_filename(self):
+ makefile = sysconfig.get_makefile_filename()
+ self.assertTrue(os.path.isfile(makefile), 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)
@@ -283,10 +289,19 @@ class SysconfigTestCase(support.EnvironGuard, unittest.TestCase):
outs, errs = p.communicate()
self.assertEqual(0, p.returncode, "Subprocess failed: " + outs)
+ def test_parse_config_h(self):
+ config_h = sysconfig.get_config_h_filename()
+ input = {}
+ with open(config_h, encoding="utf-8") as f:
+ result = sysconfig.parse_config_h(f, g=input)
+ self.assertTrue(input is result)
+ with open(config_h, encoding="utf-8") as f:
+ result = sysconfig.parse_config_h(f)
+ self.assertTrue(isinstance(result, dict))
def test_suite():
suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(SysconfigTestCase))
+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(SysconfigTestCase))
return suite
diff --git a/setuptools/_distutils/tests/test_text_file.py b/setuptools/_distutils/tests/test_text_file.py
index 7e76240a..ebac3d52 100644
--- a/setuptools/_distutils/tests/test_text_file.py
+++ b/setuptools/_distutils/tests/test_text_file.py
@@ -101,7 +101,7 @@ class TextFileTestCase(support.TempdirManager, unittest.TestCase):
in_file.close()
def test_suite():
- return unittest.makeSuite(TextFileTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(TextFileTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_unixccompiler.py b/setuptools/_distutils/tests/test_unixccompiler.py
index 63c7dd37..4574f77f 100644
--- a/setuptools/_distutils/tests/test_unixccompiler.py
+++ b/setuptools/_distutils/tests/test_unixccompiler.py
@@ -11,9 +11,12 @@ from distutils.errors import DistutilsPlatformError
from distutils.unixccompiler import UnixCCompiler
from distutils.util import _clear_cached_macosx_ver
-class UnixCCompilerTestCase(unittest.TestCase):
+from . import support
+
+class UnixCCompilerTestCase(support.TempdirManager, unittest.TestCase):
def setUp(self):
+ super().setUp()
self._backup_platform = sys.platform
self._backup_get_config_var = sysconfig.get_config_var
self._backup_get_config_vars = sysconfig.get_config_vars
@@ -23,6 +26,7 @@ class UnixCCompilerTestCase(unittest.TestCase):
self.cc = CompilerWrapper()
def tearDown(self):
+ super().tearDown()
sys.platform = self._backup_platform
sysconfig.get_config_var = self._backup_get_config_var
sysconfig.get_config_vars = self._backup_get_config_vars
@@ -237,11 +241,12 @@ class UnixCCompilerTestCase(unittest.TestCase):
# ensure that setting output_dir does not raise
# FileNotFoundError: [Errno 2] No such file or directory: 'a.out'
self.cc.output_dir = 'scratch'
+ os.chdir(self.mkdtemp())
self.cc.has_function('abort', includes=['stdlib.h'])
def test_suite():
- return unittest.makeSuite(UnixCCompilerTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(UnixCCompilerTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_upload.py b/setuptools/_distutils/tests/test_upload.py
index bca5516d..ce3e84a2 100644
--- a/setuptools/_distutils/tests/test_upload.py
+++ b/setuptools/_distutils/tests/test_upload.py
@@ -217,7 +217,7 @@ class uploadTestCase(BasePyPIRCCommandTestCase):
def test_suite():
- return unittest.makeSuite(uploadTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(uploadTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_util.py b/setuptools/_distutils/tests/test_util.py
index bf0d4333..2738388e 100644
--- a/setuptools/_distutils/tests/test_util.py
+++ b/setuptools/_distutils/tests/test_util.py
@@ -2,6 +2,7 @@
import os
import sys
import unittest
+import sysconfig as stdlib_sysconfig
from copy import copy
from test.support import run_unittest
from unittest import mock
@@ -10,12 +11,10 @@ from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError
from distutils.util import (get_platform, convert_path, change_root,
check_environ, split_quoted, strtobool,
rfc822_escape, byte_compile,
- grok_environment_error)
+ grok_environment_error, get_host_platform)
from distutils import util # used to patch _environ_checked
-from distutils.sysconfig import get_config_vars
from distutils import sysconfig
from distutils.tests import support
-import _osx_support
class UtilTestCase(support.EnvironGuard, unittest.TestCase):
@@ -63,110 +62,26 @@ class UtilTestCase(support.EnvironGuard, unittest.TestCase):
def _get_uname(self):
return self._uname
- def test_get_platform(self):
-
- # windows XP, 32bits
- os.name = 'nt'
- sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
- '[MSC v.1310 32 bit (Intel)]')
- sys.platform = 'win32'
- self.assertEqual(get_platform(), 'win32')
-
- # windows XP, amd64
- os.name = 'nt'
- sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
- '[MSC v.1310 32 bit (Amd64)]')
- sys.platform = 'win32'
- self.assertEqual(get_platform(), 'win-amd64')
-
- # macbook
- os.name = 'posix'
- sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) '
- '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]')
- sys.platform = 'darwin'
- self._set_uname(('Darwin', 'macziade', '8.11.1',
- ('Darwin Kernel Version 8.11.1: '
- 'Wed Oct 10 18:23:28 PDT 2007; '
- 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386'))
- _osx_support._remove_original_values(get_config_vars())
- get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
-
- get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
- '-fwrapv -O3 -Wall -Wstrict-prototypes')
-
- cursize = sys.maxsize
- sys.maxsize = (2 ** 31)-1
- try:
- self.assertEqual(get_platform(), 'macosx-10.3-i386')
- finally:
- sys.maxsize = cursize
-
- # macbook with fat binaries (fat, universal or fat64)
- _osx_support._remove_original_values(get_config_vars())
- get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4'
- get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot '
- '/Developer/SDKs/MacOSX10.4u.sdk '
- '-fno-strict-aliasing -fno-common '
- '-dynamic -DNDEBUG -g -O3')
-
- self.assertEqual(get_platform(), 'macosx-10.4-fat')
-
- _osx_support._remove_original_values(get_config_vars())
- os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.1'
- self.assertEqual(get_platform(), 'macosx-10.4-fat')
-
+ def test_get_host_platform(self):
+ with unittest.mock.patch('os.name', 'nt'):
+ with unittest.mock.patch('sys.version', '... [... (ARM64)]'):
+ self.assertEqual(get_host_platform(), 'win-arm64')
+ with unittest.mock.patch('sys.version', '... [... (ARM)]'):
+ self.assertEqual(get_host_platform(), 'win-arm32')
- _osx_support._remove_original_values(get_config_vars())
- get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot '
- '/Developer/SDKs/MacOSX10.4u.sdk '
- '-fno-strict-aliasing -fno-common '
- '-dynamic -DNDEBUG -g -O3')
+ with unittest.mock.patch('sys.version_info', (3, 9, 0, 'final', 0)):
+ self.assertEqual(get_host_platform(), stdlib_sysconfig.get_platform())
- self.assertEqual(get_platform(), 'macosx-10.4-intel')
-
- _osx_support._remove_original_values(get_config_vars())
- get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot '
- '/Developer/SDKs/MacOSX10.4u.sdk '
- '-fno-strict-aliasing -fno-common '
- '-dynamic -DNDEBUG -g -O3')
- self.assertEqual(get_platform(), 'macosx-10.4-fat3')
-
- _osx_support._remove_original_values(get_config_vars())
- get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot '
- '/Developer/SDKs/MacOSX10.4u.sdk '
- '-fno-strict-aliasing -fno-common '
- '-dynamic -DNDEBUG -g -O3')
- self.assertEqual(get_platform(), 'macosx-10.4-universal')
-
- _osx_support._remove_original_values(get_config_vars())
- get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot '
- '/Developer/SDKs/MacOSX10.4u.sdk '
- '-fno-strict-aliasing -fno-common '
- '-dynamic -DNDEBUG -g -O3')
-
- self.assertEqual(get_platform(), 'macosx-10.4-fat64')
-
- for arch in ('ppc', 'i386', 'x86_64', 'ppc64'):
- _osx_support._remove_original_values(get_config_vars())
- get_config_vars()['CFLAGS'] = ('-arch %s -isysroot '
- '/Developer/SDKs/MacOSX10.4u.sdk '
- '-fno-strict-aliasing -fno-common '
- '-dynamic -DNDEBUG -g -O3'%(arch,))
-
- self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,))
-
-
- # linux debian sarge
- os.name = 'posix'
- sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) '
- '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]')
- sys.platform = 'linux2'
- self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7',
- '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686'))
-
- self.assertEqual(get_platform(), 'linux-i686')
-
- # XXX more platforms to tests here
+ def test_get_platform(self):
+ with unittest.mock.patch('os.name', 'nt'):
+ with unittest.mock.patch.dict('os.environ', {'VSCMD_ARG_TGT_ARCH': 'x86'}):
+ self.assertEqual(get_platform(), 'win32')
+ with unittest.mock.patch.dict('os.environ', {'VSCMD_ARG_TGT_ARCH': 'x64'}):
+ self.assertEqual(get_platform(), 'win-amd64')
+ with unittest.mock.patch.dict('os.environ', {'VSCMD_ARG_TGT_ARCH': 'arm'}):
+ self.assertEqual(get_platform(), 'win-arm32')
+ with unittest.mock.patch.dict('os.environ', {'VSCMD_ARG_TGT_ARCH': 'arm64'}):
+ self.assertEqual(get_platform(), 'win-arm64')
def test_convert_path(self):
# linux/mac
@@ -303,7 +218,7 @@ class UtilTestCase(support.EnvironGuard, unittest.TestCase):
def test_suite():
- return unittest.makeSuite(UtilTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(UtilTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/test_version.py b/setuptools/_distutils/tests/test_version.py
index 8671cd2f..8405aa3a 100644
--- a/setuptools/_distutils/tests/test_version.py
+++ b/setuptools/_distutils/tests/test_version.py
@@ -1,11 +1,19 @@
"""Tests for distutils.version."""
import unittest
+import distutils
from distutils.version import LooseVersion
from distutils.version import StrictVersion
from test.support import run_unittest
class VersionTestCase(unittest.TestCase):
+ def setUp(self):
+ self.ctx = distutils.version.suppress_known_deprecation()
+ self.ctx.__enter__()
+
+ def tearDown(self):
+ self.ctx.__exit__(None, None, None)
+
def test_prerelease(self):
version = StrictVersion('1.2.3a1')
self.assertEqual(version.version, (1, 2, 3))
@@ -81,7 +89,7 @@ class VersionTestCase(unittest.TestCase):
(v1, v2, res))
def test_suite():
- return unittest.makeSuite(VersionTestCase)
+ return unittest.TestLoader().loadTestsFromTestCase(VersionTestCase)
if __name__ == "__main__":
run_unittest(test_suite())
diff --git a/setuptools/_distutils/tests/unix_compat.py b/setuptools/_distutils/tests/unix_compat.py
new file mode 100644
index 00000000..b7718c26
--- /dev/null
+++ b/setuptools/_distutils/tests/unix_compat.py
@@ -0,0 +1,16 @@
+import sys
+import unittest
+
+try:
+ import grp
+ import pwd
+except ImportError:
+ grp = pwd = None
+
+
+UNIX_ID_SUPPORT = grp and pwd
+UID_0_SUPPORT = UNIX_ID_SUPPORT and sys.platform != "cygwin"
+
+require_unix_id = unittest.skipUnless(
+ UNIX_ID_SUPPORT, "Requires grp and pwd support")
+require_uid_0 = unittest.skipUnless(UID_0_SUPPORT, "Requires UID 0 support")
diff --git a/setuptools/_distutils/util.py b/setuptools/_distutils/util.py
index afc23c4e..6d506d7e 100644
--- a/setuptools/_distutils/util.py
+++ b/setuptools/_distutils/util.py
@@ -9,6 +9,7 @@ import re
import importlib.util
import string
import sys
+import sysconfig
from distutils.errors import DistutilsPlatformError
from distutils.dep_util import newer
from distutils.spawn import spawn
@@ -20,82 +21,29 @@ from .py35compat import _optim_args_from_interpreter_flags
def get_host_platform():
"""Return a string that identifies the current platform. This is used mainly to
distinguish platform-specific build directories and platform-specific built
- distributions. Typically includes the OS name and version and the
- architecture (as supplied by 'os.uname()'), although the exact information
- included depends on the OS; eg. on Linux, the kernel version isn't
- particularly important.
+ distributions.
+ """
- Examples of returned values:
- linux-i586
- linux-alpha (?)
- solaris-2.6-sun4u
+ # We initially exposed platforms as defined in Python 3.9
+ # even with older Python versions when distutils was split out.
+ # Now that we delegate to stdlib sysconfig we need to restore this
+ # in case anyone has started to depend on it.
- Windows will return one of:
- win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
- win32 (all others - specifically, sys.platform is returned)
+ if sys.version_info < (3, 8):
+ if os.name == 'nt':
+ if '(arm)' in sys.version.lower():
+ return 'win-arm32'
+ if '(arm64)' in sys.version.lower():
+ return 'win-arm64'
- For other non-POSIX platforms, currently just returns 'sys.platform'.
+ if sys.version_info < (3, 9):
+ if os.name == "posix" and hasattr(os, 'uname'):
+ osname, host, release, version, machine = os.uname()
+ if osname[:3] == "aix":
+ from .py38compat import aix_platform
+ return aix_platform(osname, version, release)
- """
- if os.name == 'nt':
- if 'amd64' in sys.version.lower():
- return 'win-amd64'
- if '(arm)' in sys.version.lower():
- return 'win-arm32'
- if '(arm64)' in sys.version.lower():
- return 'win-arm64'
- return sys.platform
-
- # Set for cross builds explicitly
- if "_PYTHON_HOST_PLATFORM" in os.environ:
- return os.environ["_PYTHON_HOST_PLATFORM"]
-
- if os.name != "posix" or not hasattr(os, 'uname'):
- # XXX what about the architecture? NT is Intel or Alpha,
- # Mac OS is M68k or PPC, etc.
- return sys.platform
-
- # Try to distinguish various flavours of Unix
-
- (osname, host, release, version, machine) = os.uname()
-
- # Convert the OS name to lowercase, remove '/' characters, and translate
- # spaces (for "Power Macintosh")
- osname = osname.lower().replace('/', '')
- machine = machine.replace(' ', '_')
- machine = machine.replace('/', '-')
-
- if osname[:5] == "linux":
- # At least on Linux/Intel, 'machine' is the processor --
- # i386, etc.
- # XXX what about Alpha, SPARC, etc?
- return "%s-%s" % (osname, machine)
- elif osname[:5] == "sunos":
- if release[0] >= "5": # SunOS 5 == Solaris 2
- osname = "solaris"
- release = "%d.%s" % (int(release[0]) - 3, release[2:])
- # We can't use "platform.architecture()[0]" because a
- # bootstrap problem. We use a dict to get an error
- # if some suspicious happens.
- bitness = {2147483647:"32bit", 9223372036854775807:"64bit"}
- machine += ".%s" % bitness[sys.maxsize]
- # fall through to standard osname-release-machine representation
- elif osname[:3] == "aix":
- from .py38compat import aix_platform
- return aix_platform(osname, version, release)
- elif osname[:6] == "cygwin":
- osname = "cygwin"
- rel_re = re.compile (r'[\d.]+', re.ASCII)
- m = rel_re.match(release)
- if m:
- release = m.group()
- elif osname[:6] == "darwin":
- import _osx_support, distutils.sysconfig
- osname, release, machine = _osx_support.get_platform_osx(
- distutils.sysconfig.get_config_vars(),
- osname, release, machine)
-
- return "%s-%s-%s" % (osname, release, machine)
+ return sysconfig.get_platform()
def get_platform():
if os.name == 'nt':
@@ -242,30 +190,43 @@ def check_environ ():
def subst_vars (s, local_vars):
- """Perform shell/Perl-style variable substitution on 'string'. Every
- occurrence of '$' followed by a name is considered a variable, and
- variable is substituted by the value found in the 'local_vars'
- dictionary, or in 'os.environ' if it's not in 'local_vars'.
+ """
+ Perform variable substitution on 'string'.
+ Variables are indicated by format-style braces ("{var}").
+ Variable is substituted by the value found in the 'local_vars'
+ dictionary or in 'os.environ' if it's not in 'local_vars'.
'os.environ' is first checked/augmented to guarantee that it contains
certain values: see 'check_environ()'. Raise ValueError for any
variables not found in either 'local_vars' or 'os.environ'.
"""
check_environ()
- def _subst (match, local_vars=local_vars):
- var_name = match.group(1)
- if var_name in local_vars:
- return str(local_vars[var_name])
- else:
- return os.environ[var_name]
-
+ lookup = dict(os.environ)
+ lookup.update((name, str(value)) for name, value in local_vars.items())
try:
- return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s)
+ return _subst_compat(s).format_map(lookup)
except KeyError as var:
- raise ValueError("invalid variable '$%s'" % var)
+ raise ValueError(f"invalid variable {var}")
# subst_vars ()
+def _subst_compat(s):
+ """
+ Replace shell/Perl-style variable substitution with
+ format-style. For compatibility.
+ """
+ def _subst(match):
+ return f'{{{match.group(1)}}}'
+ repl = re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s)
+ if repl != s:
+ import warnings
+ warnings.warn(
+ "shell/Perl-style substitions are deprecated",
+ DeprecationWarning,
+ )
+ return repl
+
+
def grok_environment_error (exc, prefix="error: "):
# Function kept for backward compatibility.
# Used to try clever things with EnvironmentErrors,
diff --git a/setuptools/_distutils/version.py b/setuptools/_distutils/version.py
index c33bebae..35e181db 100644
--- a/setuptools/_distutils/version.py
+++ b/setuptools/_distutils/version.py
@@ -27,6 +27,20 @@ Every version number class implements the following interface:
"""
import re
+import warnings
+import contextlib
+
+
+@contextlib.contextmanager
+def suppress_known_deprecation():
+ with warnings.catch_warnings(record=True) as ctx:
+ warnings.filterwarnings(
+ action='default',
+ category=DeprecationWarning,
+ message="distutils Version classes are deprecated.",
+ )
+ yield ctx
+
class Version:
"""Abstract base class for version numbering classes. Just provides
@@ -36,6 +50,12 @@ class Version:
"""
def __init__ (self, vstring=None):
+ warnings.warn(
+ "distutils Version classes are deprecated. "
+ "Use packaging.version instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
if vstring:
self.parse(vstring)
@@ -165,7 +185,8 @@ class StrictVersion (Version):
def _cmp (self, other):
if isinstance(other, str):
- other = StrictVersion(other)
+ with suppress_known_deprecation():
+ other = StrictVersion(other)
elif not isinstance(other, StrictVersion):
return NotImplemented
@@ -301,11 +322,6 @@ class LooseVersion (Version):
component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE)
- def __init__ (self, vstring=None):
- if vstring:
- self.parse(vstring)
-
-
def parse (self, vstring):
# I've given up on thinking I can reconstruct the version string
# from the parsed tuple -- so I just store the string here for
diff --git a/setuptools/_distutils/versionpredicate.py b/setuptools/_distutils/versionpredicate.py
index 062c98f2..55f25d91 100644
--- a/setuptools/_distutils/versionpredicate.py
+++ b/setuptools/_distutils/versionpredicate.py
@@ -23,7 +23,9 @@ def splitUp(pred):
if not res:
raise ValueError("bad package restriction syntax: %r" % pred)
comp, verStr = res.groups()
- return (comp, distutils.version.StrictVersion(verStr))
+ with distutils.version.suppress_known_deprecation():
+ other = distutils.version.StrictVersion(verStr)
+ return (comp, other)
compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq,
">": operator.gt, ">=": operator.ge, "!=": operator.ne}
@@ -162,5 +164,6 @@ def split_provision(value):
raise ValueError("illegal provides specification: %r" % value)
ver = m.group(2) or None
if ver:
- ver = distutils.version.StrictVersion(ver)
+ with distutils.version.suppress_known_deprecation():
+ ver = distutils.version.StrictVersion(ver)
return m.group(1), ver