Imported Upstream version 59.2.0 upstream/59.2.0
authorJinWang An <jinwang.an@samsung.com>
Mon, 27 Mar 2023 08:02:39 +0000 (17:02 +0900)
committerJinWang An <jinwang.an@samsung.com>
Mon, 27 Mar 2023 08:02:39 +0000 (17:02 +0900)
20 files changed:
.bumpversion.cfg
.github/ISSUE_TEMPLATE/feature-request.yml
.github/pull_request_template.md
CHANGES.rst
README.rst
docs/deprecated/distutils/_setuptools_disclaimer.rst
docs/deprecated/distutils/apiref.rst
docs/development/developer-guide.rst
docs/pkg_resources.rst
pkg_resources/__init__.py
setup.cfg
setuptools/_distutils/__init__.py
setuptools/_distutils/command/install.py
setuptools/_distutils/command/install_egg_info.py
setuptools/_distutils/cygwinccompiler.py
setuptools/_distutils/sysconfig.py
setuptools/_distutils/tests/test_cygwinccompiler.py
setuptools/_distutils/tests/test_install.py
setuptools/_distutils/util.py
setuptools/command/easy_install.py

index c7a9e9c589509a98f49591801a4f6de9b47e0c91..a9d31cd265e224a533b11d9f5a40221c32d929cf 100644 (file)
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 59.1.1
+current_version = 59.2.0
 commit = True
 tag = True
 
index 88ae6741ffd4488e3af294811382f7313b37dc07..7bd476818ee61984a941c7e5d390046ebdf16814 100644 (file)
@@ -73,7 +73,7 @@ body:
       Have you tried to workaround the problem using other tools? Or a
       different approach to solving this issue? Please elaborate here.
     placeholder: >-
-      I tried doing X, Y and Z. But they are subobpimal because of P.
+      I tried doing X, Y and Z. But they are suboptimal because of P.
 
 - type: textarea
   attributes:
index ef5a98e727c792c2a3f9611c233c5ccb125bfe9b..41ecde17d5b84de035379100baa094079a4c1373 100644 (file)
@@ -1,4 +1,4 @@
-<!-- First time contributors: Take a moment to review https://setuptools.readthedocs.io/en/latest/development/developer-guide.html! -->
+<!-- First time contributors: Take a moment to review https://setuptools.pypa.io/en/latest/development/developer-guide.html! -->
 <!-- Remove sections if not applicable -->
 
 ## Summary of changes
@@ -15,4 +15,4 @@ Closes <!-- issue number here -->
 
 [`changelog.d/`]: https://github.com/pypa/setuptools/tree/master/changelog.d
 [PR docs]:
-https://setuptools.readthedocs.io/en/latest/development/developer-guide.html#making-a-pull-request
+https://setuptools.pypa.io/en/latest/development/developer-guide.html#making-a-pull-request
index b87e4363a230de1a1c0e4247d1095cad1257ebe1..3206647a0e9664f28fd239c6c4bbe290e44c913e 100644 (file)
@@ -1,3 +1,12 @@
+v59.2.0
+-------
+
+
+Changes
+^^^^^^^
+* #2875: Introduce changes from pypa/distutils@514e9d0, including support for overrides from Debian and pkgsrc, unlocking the possibility of making SETUPTOOLS_USE_DISTUTILS=local the default again.
+
+
 v59.1.1
 -------
 
@@ -2273,7 +2282,7 @@ v30.3.0
 
 * #394 via #862: Added support for `declarative package
   config in a setup.cfg file
-  <https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files>`_.
+  <https://setuptools.pypa.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files>`_.
 
 v30.2.1
 -------
@@ -2734,7 +2743,7 @@ v23.0.0
   about, please comment in the ticket.
 * #604: Removed docs building support. The project
   now relies on documentation hosted at
-  https://setuptools.readthedocs.io/.
+  https://setuptools.pypa.io/.
 
 v22.0.5
 -------
@@ -2884,7 +2893,7 @@ v20.6.0
   `semver <https://semver.org>`_ precisely.
   The 'v' prefix on version numbers now also allows
   version numbers to be referenced in the changelog,
-  e.g. http://setuptools.readthedocs.io/en/latest/history.html#v20-6-0.
+  e.g. http://setuptools.pypa.io/en/latest/history.html#v20-6-0.
 
 20.5
 ----
@@ -2964,7 +2973,7 @@ v20.6.0
 
 * Added support for using passwords from keyring in the upload
   command. See `the upload docs
-  <https://setuptools.readthedocs.io/en/latest/setuptools.html#upload-upload-source-and-or-egg-distributions-to-pypi>`_
+  <https://setuptools.pypa.io/en/latest/setuptools.html#upload-upload-source-and-or-egg-distributions-to-pypi>`_
   for details.
 
 20.0
@@ -3718,7 +3727,7 @@ process to fail and PyPI uploads no longer accept files for 13.0.
 ---
 
 * Added a `Developer Guide
-  <https://setuptools.readthedocs.io/en/latest/developer-guide.html>`_ to the official
+  <https://setuptools.pypa.io/en/latest/developer-guide.html>`_ to the official
   documentation.
 * Some code refactoring and cleanup was done with no intended behavioral
   changes.
@@ -5425,7 +5434,7 @@ easy_install
  * ``setuptools`` now finds its commands, ``setup()`` argument validators, and
    metadata writers using entry points, so that they can be extended by
    third-party packages. See `Creating distutils Extensions
-   <https://setuptools.readthedocs.io/en/latest/setuptools.html#creating-distutils-extensions>`_
+   <https://setuptools.pypa.io/en/latest/setuptools.html#creating-distutils-extensions>`_
    for more details.
 
  * The vestigial ``depends`` command has been removed. It was never finished
index 6e7b95cf5dc640c45c195f5b8c58bde73ae54fd5..fab411188696b99bff4e87fbfc7afecf32ccd6b1 100644 (file)
@@ -20,7 +20,7 @@
    :alt: Code style: Black
 
 .. image:: https://img.shields.io/readthedocs/setuptools/latest.svg
-    :target: https://setuptools.readthedocs.io
+    :target: https://setuptools.pypa.io
 
 .. image:: https://img.shields.io/badge/skeleton-2021-informational
    :target: https://blog.jaraco.com/skeleton
index cc75858326d44d988c90df0e6c11b48bc57579a8..628c2e4f6585cd3ac91ec52f1c679a4a55ce7a83 100644 (file)
@@ -1,5 +1,5 @@
 .. note::
 
    This document is being retained solely until the ``setuptools`` documentation
-   at https://setuptools.readthedocs.io/en/latest/setuptools.html
+   at https://setuptools.pypa.io/en/latest/setuptools.html
    independently covers all of the relevant information currently included here.
index f721fc169fb3e39d9521a406a0d76679291d1bf5..f00ed74c693d3521610b4db180ee53fd3967e51c 100644 (file)
@@ -11,7 +11,7 @@ API Reference
       and other APIs, makes the API consistent across different Python versions,
       and is hence recommended over using ``distutils`` directly.
 
-.. _New and changed setup.py arguments in setuptools: https://setuptools.readthedocs.io/en/latest/setuptools.html#new-and-changed-setup-keywords
+.. _New and changed setup.py arguments in setuptools: https://setuptools.pypa.io/en/latest/setuptools.html#new-and-changed-setup-keywords
 
 .. include:: ./_setuptools_disclaimer.rst
 
index 052ca76230b78e4f7af2d81ad5ac2b11dd06b124..f29c1a80e480a8f6fd6310eb6faf04575b3857ac 100644 (file)
@@ -110,7 +110,7 @@ To build the docs locally, use tox::
     $ tox -e docs
 
 .. _Sphinx: http://www.sphinx-doc.org/en/master/
-.. _published documentation: https://setuptools.readthedocs.io/en/latest/
+.. _published documentation: https://setuptools.pypa.io/en/latest/
 
 ---------------------
 Vendored Dependencies
index fb5fc0774fd0f6010c422776fe3afec788ee0f38..c11581896114e122cca3a2f6c31d1e522d837bd0 100644 (file)
@@ -1151,7 +1151,7 @@ paths.
     will be read as-is.
 
 ``resource_string(package_or_requirement, resource_name)``
-    Return the specified resource as a string.  The resource is read in
+    Return the specified resource as ``bytes``.  The resource is read in
     binary fashion, such that the returned string contains exactly the bytes
     that are stored in the resource.
 
index c615bc09653732b42a3c54b5abc00184c2a26cfb..42129d5b567708bb1e5e8b1ae67131eb0f984d36 100644 (file)
@@ -1484,7 +1484,7 @@ class NullProvider:
     def _validate_resource_path(path):
         """
         Validate the resource paths according to the docs.
-        https://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access
+        https://setuptools.pypa.io/en/latest/pkg_resources.html#basic-resource-access
 
         >>> warned = getfixture('recwarn')
         >>> warnings.simplefilter('always')
index 30f06b800a022da55315491317d66c394dcdf677..7909ea10df830c01c9f3d0309856bcfaf2f061b3 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = setuptools
-version = 59.1.1
+version = 59.2.0
 author = Python Packaging Authority
 author_email = distutils-sig@python.org
 description = Easily download, build, install, upgrade, and uninstall Python packages
@@ -18,7 +18,7 @@ classifiers =
        Topic :: Utilities
 keywords = CPAN PyPI distutils eggs package management
 project_urls =
-       Documentation = https://setuptools.readthedocs.io/
+       Documentation = https://setuptools.pypa.io/
 
 [options]
 packages = find_namespace:
index 7dac55b601eef6950ddf24be9170f1656cb15366..8fd493b42c76a5a630ef7eb3bb002314a9b15c94 100644 (file)
@@ -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
index e98f049133e4c12c4d7a9c976cb3a5d394b034f2..c756b6db8ac0f05a434c690a038def1fed2b2c92 100644 (file)
@@ -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
@@ -20,62 +23,62 @@ 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}/Include/{dist_name}',
+        'scripts': '{userbase}/{implementation}{py_version_nodot}/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 +86,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'
@@ -284,7 +312,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}")
 
@@ -335,6 +363,8 @@ class install(Command):
         # everything else.
         self.config_vars['base'] = self.install_base
         self.config_vars['platbase'] = self.install_platbase
+        self.config_vars['installed_base'] = (
+            sysconfig.get_config_vars()['installed_base'])
 
         if DEBUG:
             from pprint import pprint
@@ -431,10 +461,10 @@ 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:
@@ -450,7 +480,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 +492,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)
@@ -484,7 +514,7 @@ class install(Command):
                 name = 'pypy_nt'
             else:
                 name = 'pypy'
-        scheme = INSTALL_SCHEMES[name]
+        scheme = _load_schemes()[name]
         for key in SCHEME_KEYS:
             attrname = 'install_' + key
             if getattr(self, attrname) is None:
index 0ddc7367cc608dac2cfb408a08c8b442278a8207..adc0323f98fde748a70aada6930ea29fd22724b1 100644 (file)
@@ -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):
index f1c38e390cf2fd246b7fc85ca41ef91aff3daec6..f80ca62287470e187cbdde910012568156e0ab6e 100644 (file)
@@ -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)
 
index 8832b3ecebf8966796df4663d33ae6b57a4c4f7d..d36d94f76f8a5ae8b2510053811942dac6937367 100644 (file)
@@ -129,6 +129,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 +160,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 +179,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")
@@ -273,14 +280,24 @@ def get_config_h_filename():
     return os.path.join(inc_dir, 'pyconfig.h')
 
 
+# Allow this value to be patched by pkgsrc. Ref pypa/distutils#16.
+_makefile_tmpl = 'config-{python_ver}{build_flags}{multiarch}'
+
+
 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
+    multiarch = (
+        '-%s' % sys.implementation._multiarch
+        if hasattr(sys.implementation, '_multiarch') else ''
+    )
+    config_file = _makefile_tmpl.format(
+        python_ver=get_python_version(),
+        build_flags=build_flags,
+        multiarch=multiarch,
+    )
     return os.path.join(lib_dir, config_file, 'Makefile')
 
 
@@ -452,15 +469,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:
index 9dc869de4c8ef0c5bb6c482c85d1078c6d5984c0..2a02eed40d5047921371f1c95d317528c95a49b9 100644 (file)
@@ -141,10 +141,13 @@ 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():
index eb684a09e6efeed808344d6d4aa0c6e5798e82eb..cce973dc5733c22bd2aa9b2e812ffa1c938cc269 100644 (file)
@@ -94,7 +94,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'})
index afc23c4e233f5bd046daf34bce13c248fa41d488..ac6d446d681a0231892493fba10dfda450d6d71e 100644 (file)
@@ -242,30 +242,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,
index 1aed0e87036ca7ef286d3cdebdeb86b03747e932..fc848d0d1c35390ca7f3c0b22cce92079ad19a52 100644 (file)
@@ -6,7 +6,7 @@ A tool for doing automatic download/extract/build of distutils-based Python
 packages.  For detailed documentation, see the accompanying EasyInstall.txt
 file, or visit the `EasyInstall home page`__.
 
-__ https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html
+__ https://setuptools.pypa.io/en/latest/deprecated/easy_install.html
 
 """
 
@@ -519,7 +519,7 @@ class easy_install(Command):
         For information on other options, you may wish to consult the
         documentation at:
 
-          https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html
+          https://setuptools.pypa.io/en/latest/deprecated/easy_install.html
 
         Please make the appropriate changes for your system and try again.
         """).lstrip()  # noqa
@@ -1312,7 +1312,7 @@ class easy_install(Command):
         * You can set up the installation directory to support ".pth" files by
           using one of the approaches described here:
 
-          https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html#custom-installation-locations
+          https://setuptools.pypa.io/en/latest/deprecated/easy_install.html#custom-installation-locations
 
 
         Please make the appropriate changes for your system and try again.