Description: Backport ‘semver.Version.parse’ from version 3.0.
 .
 The ‘semver’ library has breaking API changes in version “3.0”, which is what
 ‘changelog-chug’ depends on. But currently in Debian (bug#1081140), no later
 than version “2.10” is available.
 .
 We add a wrapper for ‘semver.VersionInfo’ so that it has equivalent ‘parse’
 method from ‘semver’ version 3.0.
Author: Ben Finney <bignose@debian.org>
Bug-Debian: https://bugs.debian.org/1081140
Last-Update: 2024-10-25

diff --git /dev/null new/src/chug/semver_parse_backport.py
--- /dev/null
+++ new/src/chug/semver_parse_backport.py
@@ -0,0 +1,92 @@
+# src/chug/semver_parse_backport.py
+
+""" Wrapper for ‘semver’ to back-port ‘Version.parse’ from v3. """
+
+import re
+from typing import (
+    Any,
+    ClassVar,
+    Dict,
+    Pattern,
+    Type,
+    TypeVar,
+)
+
+import semver
+
+
+T = TypeVar("T", bound="Version")
+
+
+class VersionInfoWithV3Parse(semver.VersionInfo):
+    """ A minimal back-port of new ‘semver.Version.parse’ behaviour. """
+
+    _REGEX_TEMPLATE: ClassVar[
+        str
+    ] = r"""
+        ^
+        (?P<major>0|[1-9]\d*)
+        (?:
+            \.
+            (?P<minor>0|[1-9]\d*)
+            (?:
+                \.
+                (?P<patch>0|[1-9]\d*)
+            ){opt_patch}
+        ){opt_minor}
+        (?:-(?P<prerelease>
+            (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
+            (?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*
+        ))?
+        (?:\+(?P<build>
+            [0-9a-zA-Z-]+
+            (?:\.[0-9a-zA-Z-]+)*
+        ))?
+        $
+        """
+    """ Regex template for a semver version. """
+
+    _REGEX: ClassVar[Pattern[str]] = re.compile(
+        _REGEX_TEMPLATE.format(opt_patch="", opt_minor=""),
+        re.VERBOSE,
+    )
+    """ Regex for a full semver version. """
+
+    _REGEX_OPTIONAL_MINOR_AND_PATCH: ClassVar[Pattern[str]] = re.compile(
+        _REGEX_TEMPLATE.format(opt_patch="?", opt_minor="?"),
+        re.VERBOSE,
+    )
+    """ Regex for a semver version that might be shorter. """
+
+    @classmethod
+    def parse(
+            cls: Type[T],
+            version: str,
+            optional_minor_and_patch: bool = False,
+    ) -> "Version":
+        """
+        Parse `version` string to a `VersionInfo` instance.
+
+        :param version: version string
+        :param optional_minor_and_patch: if set to true, the version string to parse \
+           can contain optional minor and patch parts. Optional parts are set to zero.
+           By default (False), the version string to parse has to follow the semver
+           specification.
+        :return: a new :class:`Version` instance
+        :raises ValueError: if version is invalid
+        :raises TypeError: if version contains the wrong type
+        """
+        if optional_minor_and_patch:
+            match = cls._REGEX_OPTIONAL_MINOR_AND_PATCH.match(version)
+        else:
+            match = cls._REGEX.match(version)
+        if match is None:
+            raise ValueError(f"{version} is not valid SemVer string")
+
+        matched_version_parts: Dict[str, Any] = match.groupdict()
+        if not matched_version_parts['minor']:
+            matched_version_parts['minor'] = 0
+        if not matched_version_parts['patch']:
+            matched_version_parts['patch'] = 0
+
+        return cls(**matched_version_parts)


Local variables:
coding: utf-8
mode: diff
time-stamp-format: "%:y-%02m-%02d"
time-stamp-start: "^Last-Update:[ 	]+"
time-stamp-end: "$"
time-stamp-line-limit: 20
End:
vim: fileencoding=utf-8 filetype=diff :
