Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
_normalization.py181 linesDownload Raw Back to setuptools
1"""2Helpers for normalization as expected in wheel/sdist/module file names3and core metadata4"""5 6import re7from typing import TYPE_CHECKING8 9import packaging10 11# https://packaging.python.org/en/latest/specifications/core-metadata/#name12_VALID_NAME = re.compile(r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE)13_UNSAFE_NAME_CHARS = re.compile(r"[^A-Z0-9._-]+", re.IGNORECASE)14_NON_ALPHANUMERIC = re.compile(r"[^A-Z0-9]+", re.IGNORECASE)15_PEP440_FALLBACK = re.compile(16    r"^v?(?P<safe>(?:[0-9]+!)?[0-9]+(?:\.[0-9]+)*)", re.IGNORECASE17)18 19 20def safe_identifier(name: str) -> str:21    """Make a string safe to be used as Python identifier.22    >>> safe_identifier("12abc")23    '_12abc'24    >>> safe_identifier("__editable__.myns.pkg-78.9.3_local")25    '__editable___myns_pkg_78_9_3_local'26    """27    safe = re.sub(r'\W|^(?=\d)', '_', name)28    assert safe.isidentifier()29    return safe30 31 32def safe_name(component: str) -> str:33    """Escape a component used as a project name according to Core Metadata.34    >>> safe_name("hello world")35    'hello-world'36    >>> safe_name("hello?world")37    'hello-world'38    >>> safe_name("hello_world")39    'hello_world'40    """41    return _UNSAFE_NAME_CHARS.sub("-", component)42 43 44def safe_version(version: str) -> str:45    """Convert an arbitrary string into a valid version string.46    Can still raise an ``InvalidVersion`` exception.47    To avoid exceptions use ``best_effort_version``.48    >>> safe_version("1988 12 25")49    '1988.12.25'50    >>> safe_version("v0.2.1")51    '0.2.1'52    >>> safe_version("v0.2?beta")53    '0.2b0'54    >>> safe_version("v0.2 beta")55    '0.2b0'56    >>> safe_version("ubuntu lts")57    Traceback (most recent call last):58    ...59    packaging.version.InvalidVersion: Invalid version: 'ubuntu.lts'60    """61    v = version.replace(' ', '.')62    try:63        return str(packaging.version.Version(v))64    except packaging.version.InvalidVersion:65        attempt = _UNSAFE_NAME_CHARS.sub("-", v)66        return str(packaging.version.Version(attempt))67 68 69def best_effort_version(version: str) -> str:70    """Convert an arbitrary string into a version-like string.71    Fallback when ``safe_version`` is not safe enough.72    >>> best_effort_version("v0.2 beta")73    '0.2b0'74    >>> best_effort_version("ubuntu lts")75    '0.dev0+sanitized.ubuntu.lts'76    >>> best_effort_version("0.23ubuntu1")77    '0.23.dev0+sanitized.ubuntu1'78    >>> best_effort_version("0.23-")79    '0.23.dev0+sanitized'80    >>> best_effort_version("0.-_")81    '0.dev0+sanitized'82    >>> best_effort_version("42.+?1")83    '42.dev0+sanitized.1'84    """85    try:86        return safe_version(version)87    except packaging.version.InvalidVersion:88        v = version.replace(' ', '.')89        match = _PEP440_FALLBACK.search(v)90        if match:91            safe = match["safe"]92            rest = v[len(safe) :]93        else:94            safe = "0"95            rest = version96        safe_rest = _NON_ALPHANUMERIC.sub(".", rest).strip(".")97        local = f"sanitized.{safe_rest}".strip(".")98        return safe_version(f"{safe}.dev0+{local}")99 100 101def safe_extra(extra: str) -> str:102    """Normalize extra name according to PEP 685103    >>> safe_extra("_FrIeNdLy-._.-bArD")104    'friendly-bard'105    >>> safe_extra("FrIeNdLy-._.-bArD__._-")106    'friendly-bard'107    """108    return _NON_ALPHANUMERIC.sub("-", extra).strip("-").lower()109 110 111def filename_component(value: str) -> str:112    """Normalize each component of a filename (e.g. distribution/version part of wheel)113    Note: ``value`` needs to be already normalized.114    >>> filename_component("my-pkg")115    'my_pkg'116    """117    return value.replace("-", "_").strip("_")118 119 120def filename_component_broken(value: str) -> str:121    """122    Produce the incorrect filename component for compatibility.123 124    See pypa/setuptools#4167 for detailed analysis.125 126    TODO: replace this with filename_component after pip 24 is127    nearly-ubiquitous.128 129    >>> filename_component_broken('foo_bar-baz')130    'foo-bar-baz'131    """132    return value.replace('_', '-')133 134 135def safer_name(value: str) -> str:136    """Like ``safe_name`` but can be used as filename component for wheel"""137    # See bdist_wheel.safer_name138    return (139        # Per https://packaging.python.org/en/latest/specifications/name-normalization/#name-normalization140        re141        .sub(r"[-_.]+", "-", safe_name(value))142        .lower()143        # Per https://packaging.python.org/en/latest/specifications/binary-distribution-format/#escaping-and-unicode144        .replace("-", "_")145    )146 147 148def safer_best_effort_version(value: str) -> str:149    """Like ``best_effort_version`` but can be used as filename component for wheel"""150    # See bdist_wheel.safer_verion151    # TODO: Replace with only safe_version in the future (no need for best effort)152    return filename_component(best_effort_version(value))153 154 155def _missing_canonicalize_license_expression(expression: str) -> str:156    """157    Defer import error to affect only users that actually use it158    https://github.com/pypa/setuptools/issues/4894159    >>> _missing_canonicalize_license_expression("a OR b")160    Traceback (most recent call last):161    ...162    ImportError: ...Cannot import `packaging.licenses`...163    """164    raise ImportError(165        "Cannot import `packaging.licenses`."166        """167        Setuptools>=77.0.0 requires "packaging>=24.2" to work properly.168        Please make sure you have a suitable version installed.169        """170    )171 172 173try:174    from packaging.licenses import (175        canonicalize_license_expression as _canonicalize_license_expression,176    )177except ImportError:  # pragma: nocover178    if not TYPE_CHECKING:179        # XXX: pyright is still upset even with # pyright: ignore[reportAssignmentType]180        _canonicalize_license_expression = _missing_canonicalize_license_expression181 
codekingpro/portable-devtools · Team Ai