+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
-------
* #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
-------
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
-------
`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
----
* 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
---
* 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.
* ``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
Metadata-Version: 2.1
Name: setuptools
-Version: 59.1.1
+Version: 59.2.0
Summary: Easily download, build, install, upgrade, and uninstall Python packages
Home-page: https://github.com/pypa/setuptools
Author: Python Packaging Authority
Author-email: distutils-sig@python.org
License: UNKNOWN
-Project-URL: Documentation, https://setuptools.readthedocs.io/
+Project-URL: Documentation, https://setuptools.pypa.io/
Keywords: CPAN PyPI distutils eggs package management
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
: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
: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
.. 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.
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
$ 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
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.
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')
[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
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:
Metadata-Version: 2.1
Name: setuptools
-Version: 59.1.1
+Version: 59.2.0
Summary: Easily download, build, install, upgrade, and uninstall Python packages
Home-page: https://github.com/pypa/setuptools
Author: Python Packaging Authority
Author-email: distutils-sig@python.org
License: UNKNOWN
-Project-URL: Documentation, https://setuptools.readthedocs.io/
+Project-URL: Documentation, https://setuptools.pypa.io/
Keywords: CPAN PyPI distutils eggs package management
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
: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
"""
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
import sys
import os
+import contextlib
+import sysconfig
+import itertools
from distutils import log
from distutils.core import Command
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
# 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'
# 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}")
# 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
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:
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"""
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)
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:
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):
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)
"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).
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
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")
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')
_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:
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():
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'})
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,
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
"""
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
* 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.