Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
monkey.py127 linesDownload Raw Back to setuptools
1"""2Monkey patching of distutils.3"""4 5from __future__ import annotations6 7import inspect8import platform9import sys10import types11from typing import TypeVar, cast, overload12 13import distutils.filelist14 15_T = TypeVar("_T")16_UnpatchT = TypeVar("_UnpatchT", type, types.FunctionType)17 18 19__all__: list[str] = []20"""21Everything is private. Contact the project team22if you think you need this functionality.23"""24 25 26def _get_mro(cls):27    """28    Returns the bases classes for cls sorted by the MRO.29 30    Works around an issue on Jython where inspect.getmro will not return all31    base classes if multiple classes share the same name. Instead, this32    function will return a tuple containing the class itself, and the contents33    of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024.34    """35    if platform.python_implementation() == "Jython":36        return (cls,) + cls.__bases__37    return inspect.getmro(cls)38 39 40@overload41def get_unpatched(item: _UnpatchT) -> _UnpatchT: ...42@overload43def get_unpatched(item: object) -> None: ...44def get_unpatched(45    item: type | types.FunctionType | object,46) -> type | types.FunctionType | None:47    if isinstance(item, type):48        return get_unpatched_class(item)49    if isinstance(item, types.FunctionType):50        return get_unpatched_function(item)51    return None52 53 54def get_unpatched_class(cls: type[_T]) -> type[_T]:55    """Protect against re-patching the distutils if reloaded56 57    Also ensures that no other distutils extension monkeypatched the distutils58    first.59    """60    external_bases = (61        cast(type[_T], cls)62        for cls in _get_mro(cls)63        if not cls.__module__.startswith('setuptools')64    )65    base = next(external_bases)66    if not base.__module__.startswith('distutils'):67        msg = f"distutils has already been patched by {cls!r}"68        raise AssertionError(msg)69    return base70 71 72def patch_all() -> None:73    import setuptools74 75    # we can't patch distutils.cmd, alas76    distutils.core.Command = setuptools.Command  # type: ignore[misc,assignment] # monkeypatching77 78    _patch_distribution_metadata()79 80    # Install Distribution throughout the distutils81    for module in distutils.dist, distutils.core, distutils.cmd:82        module.Distribution = setuptools.dist.Distribution83 84    # Install the patched Extension85    distutils.core.Extension = setuptools.extension.Extension  # type: ignore[misc,assignment] # monkeypatching86    distutils.extension.Extension = setuptools.extension.Extension  # type: ignore[misc,assignment] # monkeypatching87    if 'distutils.command.build_ext' in sys.modules:88        sys.modules[89            'distutils.command.build_ext'90        ].Extension = setuptools.extension.Extension91 92 93def _patch_distribution_metadata():94    from . import _core_metadata95 96    """Patch write_pkg_file and read_pkg_file for higher metadata standards"""97    for attr in (98        'write_pkg_info',99        'write_pkg_file',100        'read_pkg_file',101        'get_metadata_version',102        'get_fullname',103    ):104        new_val = getattr(_core_metadata, attr)105        setattr(distutils.dist.DistributionMetadata, attr, new_val)106 107 108def patch_func(replacement, target_mod, func_name) -> None:109    """110    Patch func_name in target_mod with replacement111 112    Important - original must be resolved by name to avoid113    patching an already patched function.114    """115    original = getattr(target_mod, func_name)116 117    # set the 'unpatched' attribute on the replacement to118    # point to the original.119    vars(replacement).setdefault('unpatched', original)120 121    # replace the function in the original module122    setattr(target_mod, func_name, replacement)123 124 125def get_unpatched_function(candidate):126    return candidate.unpatched127 
codekingpro/portable-devtools · Team Ai