[bumpversion]
-current_version = 65.0.2
+current_version = 65.1.0
commit = True
tag = True
+v65.1.0
+-------
+
+
+Changes
+^^^^^^^
+* #3536: Remove monkeypatching of msvc9compiler.
+
+Documentation changes
+^^^^^^^^^^^^^^^^^^^^^
+* #3538: Corrected documentation on how to use the `legacy-editable` mode.
+
+
v65.0.2
-------
``sdist``. This allows plugins and customization scripts to automatically
add required source files in the source distribution.
* #3414: Users can *temporarily* specify an environment variable
- ``SETUPTOOLS_ENABLE_FEATURE=legacy-editable`` as a escape hatch for the
+ ``SETUPTOOLS_ENABLE_FEATURES=legacy-editable`` as a escape hatch for the
:pep:`660` behavior. This setting is **transitional** and may be removed in the
future.
* #3484: Added *transient* ``compat`` mode to editable installs.
.. code-block::
- SETUPTOOLS_USE_FEATURE="legacy-editable"
+ SETUPTOOLS_ENABLE_FEATURES="legacy-editable"
This *may* cause the installer (e.g. ``pip``) to effectively run the "legacy"
installation command: ``python setup.py develop`` [#installer]_.
├── __init__.py
└── ... (other Python files)
-With :ref:`build installed in you system <install-build>`, you can then run::
+With :ref:`build installed in your system <install-build>`, you can then run::
python -m build
[metadata]
name = setuptools
-version = 65.0.2
+version = 65.1.0
author = Python Packaging Authority
author_email = distutils-sig@python.org
description = Easily download, build, install, upgrade, and uninstall Python packages
"""
Prepare the parameters for patch_func to patch indicated function.
"""
- repl_prefix = 'msvc9_' if 'msvc9' in mod_name else 'msvc14_'
+ repl_prefix = 'msvc14_'
repl_name = repl_prefix + func_name.lstrip('_')
repl = getattr(msvc, repl_name)
mod = import_module(mod_name)
raise ImportError(func_name)
return repl, mod, func_name
- # Python 2.7 to 3.4
- msvc9 = functools.partial(patch_params, 'distutils.msvc9compiler')
-
# Python 3.5+
msvc14 = functools.partial(patch_params, 'distutils._msvccompiler')
- try:
- # Patch distutils.msvc9compiler
- patch_func(*msvc9('find_vcvarsall'))
- patch_func(*msvc9('query_vcvarsall'))
- except ImportError:
- pass
-
try:
# Patch distutils._msvccompiler._get_vc_env
patch_func(*msvc14('_get_vc_env'))
Known supported compilers:
--------------------------
-Microsoft Visual C++ 9.0:
- Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
- Microsoft Windows SDK 6.1 (x86, x64, ia64)
- Microsoft Windows SDK 7.0 (x86, x64, ia64)
-
-Microsoft Visual C++ 10.0:
- Microsoft Windows SDK 7.1 (x86, x64, ia64)
-
Microsoft Visual C++ 14.X:
Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)
Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)
environ = dict()
-_msvc9_suppress_errors = (
- # msvc9compiler isn't available on some platforms
- ImportError,
-
- # msvc9compiler raises DistutilsPlatformError in some
- # environments. See #1118.
- distutils.errors.DistutilsPlatformError,
-)
-
-try:
- from distutils.msvc9compiler import Reg
-except _msvc9_suppress_errors:
- pass
-
-
-def msvc9_find_vcvarsall(version):
- """
- Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone
- compiler build for Python
- (VCForPython / Microsoft Visual C++ Compiler for Python 2.7).
-
- Fall back to original behavior when the standalone compiler is not
- available.
-
- Redirect the path of "vcvarsall.bat".
-
- Parameters
- ----------
- version: float
- Required Microsoft Visual C++ version.
-
- Return
- ------
- str
- vcvarsall.bat path
- """
- vc_base = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f'
- key = vc_base % ('', version)
- try:
- # Per-user installs register the compiler path here
- productdir = Reg.get_value(key, "installdir")
- except KeyError:
- try:
- # All-user installs on a 64-bit system register here
- key = vc_base % ('Wow6432Node\\', version)
- productdir = Reg.get_value(key, "installdir")
- except KeyError:
- productdir = None
-
- if productdir:
- vcvarsall = join(productdir, "vcvarsall.bat")
- if isfile(vcvarsall):
- return vcvarsall
-
- return get_unpatched(msvc9_find_vcvarsall)(version)
-
-
-def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs):
- """
- Patched "distutils.msvc9compiler.query_vcvarsall" for support extra
- Microsoft Visual C++ 9.0 and 10.0 compilers.
-
- Set environment without use of "vcvarsall.bat".
-
- Parameters
- ----------
- ver: float
- Required Microsoft Visual C++ version.
- arch: str
- Target architecture.
-
- Return
- ------
- dict
- environment
- """
- # Try to get environment from vcvarsall.bat (Classical way)
- try:
- orig = get_unpatched(msvc9_query_vcvarsall)
- return orig(ver, arch, *args, **kwargs)
- except distutils.errors.DistutilsPlatformError:
- # Pass error if Vcvarsall.bat is missing
- pass
- except ValueError:
- # Pass error if environment not set after executing vcvarsall.bat
- pass
-
- # If error, try to set environment directly
- try:
- return EnvironmentInfo(arch, ver).return_env()
- except distutils.errors.DistutilsPlatformError as exc:
- _augment_exception(exc, ver, arch)
- raise
-
def _msvc14_find_vc2015():
"""Python 3.8 "distutils/_msvccompiler.py" backport"""
+++ /dev/null
-"""
-Tests for msvc support module.
-"""
-
-import os
-import contextlib
-import distutils.errors
-import mock
-
-import pytest
-
-from . import contexts
-
-# importing only setuptools should apply the patch
-__import__('setuptools')
-
-pytest.importorskip("distutils.msvc9compiler")
-
-
-def mock_reg(hkcu=None, hklm=None):
- """
- Return a mock for distutils.msvc9compiler.Reg, patched
- to mock out the functions that access the registry.
- """
-
- _winreg = getattr(distutils.msvc9compiler, '_winreg', None)
- winreg = getattr(distutils.msvc9compiler, 'winreg', _winreg)
-
- hives = {
- winreg.HKEY_CURRENT_USER: hkcu or {},
- winreg.HKEY_LOCAL_MACHINE: hklm or {},
- }
-
- @classmethod
- def read_keys(cls, base, key):
- """Return list of registry keys."""
- hive = hives.get(base, {})
- return [
- k.rpartition('\\')[2]
- for k in hive if k.startswith(key.lower())
- ]
-
- @classmethod
- def read_values(cls, base, key):
- """Return dict of registry keys and values."""
- hive = hives.get(base, {})
- return dict(
- (k.rpartition('\\')[2], hive[k])
- for k in hive if k.startswith(key.lower())
- )
-
- return mock.patch.multiple(
- distutils.msvc9compiler.Reg,
- read_keys=read_keys, read_values=read_values)
-
-
-class TestModulePatch:
- """
- Ensure that importing setuptools is sufficient to replace
- the standard find_vcvarsall function with a version that
- recognizes the "Visual C++ for Python" package.
- """
-
- key_32 = r'software\microsoft\devdiv\vcforpython\9.0\installdir'
- key_64 = key_32.replace(r'\microsoft', r'\wow6432node\microsoft')
-
- def test_patched(self):
- "Test the module is actually patched"
- mod_name = distutils.msvc9compiler.find_vcvarsall.__module__
- assert mod_name == "setuptools.msvc", "find_vcvarsall unpatched"
-
- def test_no_registry_entries_means_nothing_found(self):
- """
- No registry entries or environment variable should lead to an error
- directing the user to download vcpython27.
- """
- find_vcvarsall = distutils.msvc9compiler.find_vcvarsall
- query_vcvarsall = distutils.msvc9compiler.query_vcvarsall
-
- with contexts.environment(VS90COMNTOOLS=None):
- with mock_reg():
- assert find_vcvarsall(9.0) is None
-
- try:
- query_vcvarsall(9.0)
- except Exception as exc:
- expected = distutils.errors.DistutilsPlatformError
- assert isinstance(exc, expected)
- assert 'aka.ms/vcpython27' in str(exc)
-
- @pytest.fixture
- def user_preferred_setting(self):
- """
- Set up environment with different install dirs for user vs. system
- and yield the user_install_dir for the expected result.
- """
- with self.mock_install_dir() as user_install_dir:
- with self.mock_install_dir() as system_install_dir:
- reg = mock_reg(
- hkcu={
- self.key_32: user_install_dir,
- },
- hklm={
- self.key_32: system_install_dir,
- self.key_64: system_install_dir,
- },
- )
- with reg:
- yield user_install_dir
-
- def test_prefer_current_user(self, user_preferred_setting):
- """
- Ensure user's settings are preferred.
- """
- result = distutils.msvc9compiler.find_vcvarsall(9.0)
- expected = os.path.join(user_preferred_setting, 'vcvarsall.bat')
- assert expected == result
-
- @pytest.fixture
- def local_machine_setting(self):
- """
- Set up environment with only the system environment configured.
- """
- with self.mock_install_dir() as system_install_dir:
- reg = mock_reg(
- hklm={
- self.key_32: system_install_dir,
- },
- )
- with reg:
- yield system_install_dir
-
- def test_local_machine_recognized(self, local_machine_setting):
- """
- Ensure machine setting is honored if user settings are not present.
- """
- result = distutils.msvc9compiler.find_vcvarsall(9.0)
- expected = os.path.join(local_machine_setting, 'vcvarsall.bat')
- assert expected == result
-
- @pytest.fixture
- def x64_preferred_setting(self):
- """
- Set up environment with 64-bit and 32-bit system settings configured
- and yield the canonical location.
- """
- with self.mock_install_dir() as x32_dir:
- with self.mock_install_dir() as x64_dir:
- reg = mock_reg(
- hklm={
- # This *should* only exist on 32-bit machines
- self.key_32: x32_dir,
- # This *should* only exist on 64-bit machines
- self.key_64: x64_dir,
- },
- )
- with reg:
- yield x32_dir
-
- def test_ensure_64_bit_preferred(self, x64_preferred_setting):
- """
- Ensure 64-bit system key is preferred.
- """
- result = distutils.msvc9compiler.find_vcvarsall(9.0)
- expected = os.path.join(x64_preferred_setting, 'vcvarsall.bat')
- assert expected == result
-
- @staticmethod
- @contextlib.contextmanager
- def mock_install_dir():
- """
- Make a mock install dir in a unique location so that tests can
- distinguish which dir was detected in a given scenario.
- """
- with contexts.tempdir() as result:
- vcvarsall = os.path.join(result, 'vcvarsall.bat')
- with open(vcvarsall, 'w'):
- pass
- yield result