This commit is contained in:
ton
2024-10-07 10:13:40 +07:00
parent aa1631742f
commit 3a7d696db6
9729 changed files with 1832837 additions and 161742 deletions

View File

@@ -2,17 +2,21 @@
Monkey patching of distutils.
"""
import functools
from __future__ import annotations
import inspect
import platform
import sys
import types
from importlib import import_module
from typing import Type, TypeVar, cast, overload
import distutils.filelist
_T = TypeVar("_T")
_UnpatchT = TypeVar("_UnpatchT", type, types.FunctionType)
__all__ = []
__all__: list[str] = []
"""
Everything is private. Contact the project team
if you think you need this functionality.
@@ -33,25 +37,30 @@ def _get_mro(cls):
return inspect.getmro(cls)
def get_unpatched(item):
lookup = (
get_unpatched_class
if isinstance(item, type)
else get_unpatched_function
if isinstance(item, types.FunctionType)
else lambda item: None
)
return lookup(item)
@overload
def get_unpatched(item: _UnpatchT) -> _UnpatchT: ...
@overload
def get_unpatched(item: object) -> None: ...
def get_unpatched(
item: type | types.FunctionType | object,
) -> type | types.FunctionType | None:
if isinstance(item, type):
return get_unpatched_class(item)
if isinstance(item, types.FunctionType):
return get_unpatched_function(item)
return None
def get_unpatched_class(cls):
def get_unpatched_class(cls: type[_T]) -> type[_T]:
"""Protect against re-patching the distutils if reloaded
Also ensures that no other distutils extension monkeypatched the distutils
first.
"""
external_bases = (
cls for cls in _get_mro(cls) if not cls.__module__.startswith('setuptools')
cast(Type[_T], cls)
for cls in _get_mro(cls)
if not cls.__module__.startswith('setuptools')
)
base = next(external_bases)
if not base.__module__.startswith('distutils'):
@@ -66,21 +75,6 @@ def patch_all():
# we can't patch distutils.cmd, alas
distutils.core.Command = setuptools.Command
has_issue_12885 = sys.version_info <= (3, 5, 3)
if has_issue_12885:
# fix findall bug in distutils (http://bugs.python.org/issue12885)
distutils.filelist.findall = setuptools.findall
needs_warehouse = (3, 4) < sys.version_info < (3, 4, 6) or (
3,
5,
) < sys.version_info <= (3, 5, 3)
if needs_warehouse:
warehouse = 'https://upload.pypi.org/legacy/'
distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse
_patch_distribution_metadata()
# Install Distribution throughout the distutils
@@ -95,8 +89,6 @@ def patch_all():
'distutils.command.build_ext'
].Extension = setuptools.extension.Extension
patch_for_msvc_specialized_compiler()
def _patch_distribution_metadata():
from . import _core_metadata
@@ -107,6 +99,7 @@ def _patch_distribution_metadata():
'write_pkg_file',
'read_pkg_file',
'get_metadata_version',
'get_fullname',
):
new_val = getattr(_core_metadata, attr)
setattr(distutils.dist.DistributionMetadata, attr, new_val)
@@ -130,38 +123,4 @@ def patch_func(replacement, target_mod, func_name):
def get_unpatched_function(candidate):
return getattr(candidate, 'unpatched')
def patch_for_msvc_specialized_compiler():
"""
Patch functions in distutils to use standalone Microsoft Visual C++
compilers.
"""
# import late to avoid circular imports on Python < 3.5
msvc = import_module('setuptools.msvc')
if platform.system() != 'Windows':
# Compilers only available on Microsoft Windows
return
def patch_params(mod_name, func_name):
"""
Prepare the parameters for patch_func to patch indicated function.
"""
repl_prefix = 'msvc14_'
repl_name = repl_prefix + func_name.lstrip('_')
repl = getattr(msvc, repl_name)
mod = import_module(mod_name)
if not hasattr(mod, func_name):
raise ImportError(func_name)
return repl, mod, func_name
# Python 3.5+
msvc14 = functools.partial(patch_params, 'distutils._msvccompiler')
try:
# Patch distutils._msvccompiler._get_vc_env
patch_func(*msvc14('_get_vc_env'))
except ImportError:
pass
return candidate.unpatched