From 9a06b7c3c5b223af84f6d4b669d9d606d7611f14 Mon Sep 17 00:00:00 2001 From: Huanyi Xie <74809554+xiehuanyi@users.noreply.github.com> Date: Sun, 11 Oct 2026 21:32:19 +0300 Subject: [PATCH 1/3] Annotate existing bytes support in Version.is_valid --- changelog.d/pr495.bugfix.rst | 1 + src/semver/version.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog.d/pr495.bugfix.rst diff --git a/changelog.d/pr495.bugfix.rst b/changelog.d/pr495.bugfix.rst new file mode 100644 index 00000000..ac01fa8c --- /dev/null +++ b/changelog.d/pr495.bugfix.rst @@ -0,0 +1 @@ +The type annotation of ``Version.is_valid()`` now includes its existing support for UTF-8 encoded byte strings. diff --git a/src/semver/version.py b/src/semver/version.py index 7ead382e..6160bf73 100644 --- a/src/semver/version.py +++ b/src/semver/version.py @@ -789,7 +789,7 @@ def replace(self, **parts: Union[int, Optional[str]]) -> "Version": raise TypeError(error) @classmethod - def is_valid(cls, version: str) -> bool: + def is_valid(cls, version: String) -> bool: """ Check if the string is a valid semver version. @@ -798,7 +798,7 @@ def is_valid(cls, version: str) -> bool: .. versionchanged:: 3.0.0 Renamed from :meth:`~semver.version.Version.isvalid` - :param version: the version string to check + :param version: the version string to check, as str or UTF-8 encoded bytes :return: True if the version string is a valid semver version, False otherwise. """ From 40b14bfe9e15eddaa84a9b83c2b5e0b196b72adb Mon Sep 17 00:00:00 2001 From: Huanyi Xie <74809554+xiehuanyi@users.noreply.github.com> Date: Mon, 12 Oct 2026 19:39:14 +0300 Subject: [PATCH 2/3] Test is_valid with valid, invalid and non-UTF-8 bytes --- tests/test_semver.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_semver.py b/tests/test_semver.py index 9978b940..395d86a5 100644 --- a/tests/test_semver.py +++ b/tests/test_semver.py @@ -2,6 +2,8 @@ from semver import Version +_UTF8_VERSION = "1.0.0" + @pytest.mark.parametrize( "string,expected", [("rc", "rc"), ("rc.1", "rc.2"), ("2x", "3x")] @@ -77,6 +79,19 @@ def test_should_versioninfo_isvalid(): assert Version.is_valid("foo") is False +@pytest.mark.parametrize( + "version,expected", + [ + pytest.param(b"1.0.0", True, id="valid-bytes"), + pytest.param(b"foo", False, id="invalid-version-bytes"), + pytest.param(_UTF8_VERSION.encode("UTF-8"), True, id="utf8-encoded-version"), + pytest.param(b"\xff", False, id="invalid-utf8"), + ], +) +def test_is_valid_bytes(version, expected): + assert Version.is_valid(version) is expected + + def test_versioninfo_compare_should_raise_when_passed_invalid_value(): with pytest.raises(TypeError): Version(1, 2, 3).compare(4) From 27b05258718bfca85212305324bb6be2ba7a5241 Mon Sep 17 00:00:00 2001 From: Tom Schraitle Date: Sun, 18 Oct 2026 08:57:58 +0200 Subject: [PATCH 3/3] Remove leading underscore in variable --- tests/test_semver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_semver.py b/tests/test_semver.py index 395d86a5..fabf8276 100644 --- a/tests/test_semver.py +++ b/tests/test_semver.py @@ -2,7 +2,7 @@ from semver import Version -_UTF8_VERSION = "1.0.0" +UTF8_VERSION = "1.0.0" @pytest.mark.parametrize( @@ -84,7 +84,7 @@ def test_should_versioninfo_isvalid(): [ pytest.param(b"1.0.0", True, id="valid-bytes"), pytest.param(b"foo", False, id="invalid-version-bytes"), - pytest.param(_UTF8_VERSION.encode("UTF-8"), True, id="utf8-encoded-version"), + pytest.param(UTF8_VERSION.encode("UTF-8"), True, id="utf8-encoded-version"), pytest.param(b"\xff", False, id="invalid-utf8"), ], )