chore(lsprotocol): migrate to 2025.0.0 and cleanup artifacts

The changes align the project with the 2025.0.0 lsprotocol
release, removing the old backport and updating type hints
in the protocol hooks to use Sequence where appropriate. The
dist-info and packaging metadata for older lsprotocol
versions are replaced with the new 2025.0.0 artifacts.

- Remove exceptiongroup backport used on Python <3.11
- Use Sequence instead of List in LS protocol hooks
- Replace old dist-info with 2025.0.0 metadata
This commit is contained in:
Christoph Brandau
2026-09-03 08:39:12 +02:00
parent a0a0d38fe5
commit 53ebc5d055
101 changed files with 13838 additions and 7624 deletions
+84 -10
View File
@@ -5,9 +5,9 @@
from __future__ import annotations
import re
from typing import NewType, Tuple, Union, cast
from typing import NewType, Union, cast
from .tags import Tag, UnsortedTagsError, parse_tag
from .tags import InvalidTag, Tag, UnsortedTagsError, parse_tag
from .version import InvalidVersion, Version, _TrimmedRelease
__all__ = [
@@ -28,29 +28,42 @@ def __dir__() -> list[str]:
return __all__
BuildTag = Union[Tuple[()], Tuple[int, str]]
BuildTag = Union[tuple[()], tuple[int, str]]
"""
A wheel build tag: an empty tuple, or a ``(build number, build tag suffix)`` pair.
.. versionadded:: 20.9
"""
NormalizedName = NewType("NormalizedName", str)
"""
A :class:`typing.NewType` of :class:`str`, representing a normalized name.
.. versionadded:: 20.4
"""
class InvalidName(ValueError):
"""
An invalid distribution name; users should refer to the packaging user guide.
.. versionadded:: 23.2
"""
class InvalidWheelFilename(ValueError):
"""
An invalid wheel filename was found, users should refer to PEP 427.
.. versionadded:: 20.9
"""
class InvalidSdistFilename(ValueError):
"""
An invalid sdist filename was found, users should refer to the packaging user guide.
.. versionadded:: 20.9
"""
@@ -58,9 +71,12 @@ class InvalidSdistFilename(ValueError):
_validate_regex = re.compile(
r"[a-z0-9]|[a-z0-9][a-z0-9._-]*[a-z0-9]", re.IGNORECASE | re.ASCII
)
_normalized_regex = re.compile(r"[a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9]", re.ASCII)
_normalized_regex = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*", re.ASCII)
# PEP 427: The build number must start with a digit.
_build_tag_regex = re.compile(r"(\d+)(.*)", re.ASCII)
# PEP 427: Valid characters for an escaped project name in a wheel filename.
# Requires at least one character so an empty project name is rejected.
_wheel_name_regex = re.compile(r"^[\w._]+\Z", re.UNICODE)
def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
@@ -87,6 +103,14 @@ def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
'oslo-concurrency'
>>> canonicalize_name("requests")
'requests'
.. versionadded:: 16.2
.. versionchanged:: 20.4
The return type was changed to :class:`NormalizedName`.
.. versionchanged:: 23.2
Added the *validate* keyword parameter.
"""
if validate and not _validate_regex.fullmatch(name):
raise InvalidName(f"name is invalid: {name!r}")
@@ -102,16 +126,27 @@ def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
def is_normalized_name(name: str) -> bool:
"""
Check if a name is already normalized (i.e. :func:`canonicalize_name` would
roundtrip to the same value).
Check if a name is a normalized project name (i.e. a valid name that
:func:`canonicalize_name` would roundtrip to the same value).
The roundtrip only characterizes normalized names for *valid* names. A name
must start and end with an ASCII letter or digit, which
:func:`canonicalize_name` does not enforce: it leaves a leading or trailing
hyphen in place, so such a name roundtrips without being normalized.
:param str name: The name to check.
>>> from packaging.utils import is_normalized_name
>>> from packaging.utils import canonicalize_name, is_normalized_name
>>> is_normalized_name("requests")
True
>>> is_normalized_name("Django")
False
>>> canonicalize_name("_not_legal")
'-not-legal'
>>> is_normalized_name("-not-legal") # roundtrips, but not a valid name
False
.. versionadded:: 23.2
"""
return _normalized_regex.fullmatch(name) is not None
@@ -145,6 +180,14 @@ def canonicalize_version(
>>> canonicalize_version('1.4.0.0.0')
'1.4'
.. versionadded:: 17.1
.. versionchanged:: 21.0
The return type was narrowed to :class:`str`.
.. versionchanged:: 22.0
Added the *strip_trailing_zero* keyword parameter.
"""
if isinstance(version, str):
try:
@@ -196,8 +239,18 @@ def parse_wheel_filename(
>>> not build
True
.. versionadded:: 20.9
.. versionchanged:: 23.2
Raises :class:`InvalidWheelFilename` when the version component is invalid.
.. versionadded:: 26.1
The *validate_order* parameter.
.. versionchanged:: 26.3
Raises :class:`InvalidWheelFilename` when an interpreter component is
not an identifier, a tag set component is empty, or the project name is
empty.
"""
if not filename.endswith(".whl"):
raise InvalidWheelFilename(
@@ -214,7 +267,7 @@ def parse_wheel_filename(
parts = filename.split("-", dashes - 2)
name_part = parts[0]
# See PEP 427 for the rules on escaping the project name.
if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:
if "__" in name_part or _wheel_name_regex.match(name_part) is None:
raise InvalidWheelFilename(f"Invalid project name: {filename!r}")
name = canonicalize_name(name_part)
@@ -243,6 +296,10 @@ def parse_wheel_filename(
f"Invalid wheel filename (compressed tag set components must be in "
f"sorted order per PEP 425): {filename!r}"
) from None
except InvalidTag:
raise InvalidWheelFilename(
f"Invalid wheel filename (invalid tag component): {filename!r}"
) from None
return (name, version, build, tags)
@@ -255,8 +312,10 @@ def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
:param str filename: The name of the sdist file.
:raises InvalidSdistFilename: If the filename does not end
with an sdist extension (``.zip`` or ``.tar.gz``), or if it does not
contain a dash separating the name and the version of the distribution.
with an sdist extension (``.zip`` or ``.tar.gz``), if it does not
contain a dash separating the name and the version of the distribution,
if the project name is empty, or if the version portion is not a valid
version.
>>> from packaging.utils import parse_sdist_filename
>>> from packaging.version import Version
@@ -266,6 +325,17 @@ def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
>>> ver == Version('1.0')
True
.. versionadded:: 20.9
.. versionchanged:: 21.0
Added support for ``.zip`` source distributions.
.. versionchanged:: 23.2
Raises :class:`InvalidSdistFilename` when the version component is invalid.
.. versionchanged:: 26.3
Raises :class:`InvalidSdistFilename` on an empty project name.
.. _Source distribution format: https://packaging.python.org/specifications/source-distribution-format/#source-distribution-file-name
"""
if filename.endswith(".tar.gz"):
@@ -283,6 +353,10 @@ def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
name_part, sep, version_part = file_stem.rpartition("-")
if not sep:
raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}")
if not name_part:
raise InvalidSdistFilename(
f"Invalid sdist filename (empty project name): {filename!r}"
)
name = canonicalize_name(name_part)