/
niceSOFT
/
packaging
Обзор
Документация
Войти
/
niceSOFT
/
packaging
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/test_utils.py
255 строк
8 KB
deepakganesh78
fix: reject invalid interpreter tags (#1351)
28 июл 2026, 06:40
Не верифицирован
28 июл 2026, 06:40
26fa1d4
Код
Авторство
О чём код?
# This file is dual licensed under the terms of the Apache License, Version # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. from __future__ import annotations import pytest from packaging.tags import Tag from packaging.utils import ( InvalidName, InvalidSdistFilename, InvalidWheelFilename, canonicalize_name, canonicalize_version, is_normalized_name, parse_sdist_filename, parse_wheel_filename, ) from packaging.version import Version @pytest.mark.parametrize( ("name", "expected"), [ ("foo", "foo"), ("Foo", "foo"), ("fOo", "foo"), ("foo.bar", "foo-bar"), ("Foo.Bar", "foo-bar"), ("Foo.....Bar", "foo-bar"), ("foo_bar", "foo-bar"), ("foo___bar", "foo-bar"), ("foo-bar", "foo-bar"), ("foo----bar", "foo-bar"), ], ) def test_canonicalize_name(name: str, expected: str) -> None: assert canonicalize_name(name) == expected @pytest.mark.parametrize( ("name", "expected"), [ ("_not_legal", "-not-legal"), ("hi\n", "hi\n"), ("\nhi", "\nhi"), ("h\ni", "h\ni"), ("hi\r", "hi\r"), ("\rhi", "\rhi"), ("h\ri", "h\ri"), ], ) def test_canonicalize_name_invalid(name: str, expected: str) -> None: with pytest.raises(InvalidName): canonicalize_name(name, validate=True) assert canonicalize_name(name) == expected @pytest.mark.parametrize( ("name", "expected"), [ ("foo", "foo"), ("Foo", "foo"), ("fOo", "foo"), ("foo.bar", "foo-bar"), ("Foo.Bar", "foo-bar"), ("Foo.....Bar", "foo-bar"), ("foo_bar", "foo-bar"), ("foo___bar", "foo-bar"), ("foo-bar", "foo-bar"), ("foo----bar", "foo-bar"), ("a--b", "a-b"), ("1--1", "1-1"), ], ) def test_is_normalized_name(name: str, expected: str) -> None: assert is_normalized_name(expected) if name != expected: assert not is_normalized_name(name) @pytest.mark.parametrize( ("version", "expected"), [ (Version("1.4.0"), "1.4"), ("1.4.0", "1.4"), ("1.40.0", "1.40"), ("1.4.0.0.00.000.0000", "1.4"), ("1.0", "1"), ("1.0+abc", "1+abc"), ("1.0.dev0", "1.dev0"), ("1.0.post0", "1.post0"), ("1.0a0", "1a0"), ("1.0rc0", "1rc0"), ("100!0.0", "100!0"), # improper version strings are unchanged ("lolwat", "lolwat"), ("1.0.1-test7", "1.0.1-test7"), ], ) def test_canonicalize_version(version: str, expected: str) -> None: assert canonicalize_version(version) == expected @pytest.mark.parametrize(("version"), ["1.4.0", "1.0"]) def test_canonicalize_version_no_strip_trailing_zero(version: str) -> None: assert canonicalize_version(version, strip_trailing_zero=False) == version @pytest.mark.parametrize( ("filename", "name", "version", "build", "tags"), [ ( "foo-1.0-py3-none-any.whl", "foo", Version("1.0"), (), {Tag("py3", "none", "any")}, ), ( "some_PACKAGE-1.0-py3-none-any.whl", "some-package", Version("1.0"), (), {Tag("py3", "none", "any")}, ), ( "foo-1.0-1000-py3-none-any.whl", "foo", Version("1.0"), (1000, ""), {Tag("py3", "none", "any")}, ), ( "foo-1.0-1000abc-py3-none-any.whl", "foo", Version("1.0"), (1000, "abc"), {Tag("py3", "none", "any")}, ), ( "pyvirtualcam-0.13.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", "pyvirtualcam", Version("0.13.0"), (), { Tag("cp310", "cp310", "manylinux2014_x86_64"), Tag("cp310", "cp310", "manylinux_2_17_x86_64"), }, ), ( "foo-2-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", "foo", Version("2"), (), { Tag("py2", "none", "manylinux_2_17_x86_64"), Tag("py2", "none", "manylinux2014_x86_64"), Tag("py3", "none", "manylinux_2_17_x86_64"), Tag("py3", "none", "manylinux2014_x86_64"), }, ), ( "foo_bár-1.0-py3-none-any.whl", "foo-bár", Version("1.0"), (), {Tag("py3", "none", "any")}, ), ( "foo_bár-1.0-1000-py3-none-any.whl", "foo-bár", Version("1.0"), (1000, ""), {Tag("py3", "none", "any")}, ), ], ) def test_parse_wheel_filename( filename: str, name: str, version: Version, build: tuple[int, str], tags: set[Tag] ) -> None: assert parse_wheel_filename(filename) == (name, version, build, frozenset(tags)) @pytest.mark.parametrize( ("filename"), [ ("foo-1.0.whl"), # Missing tags ("foo-1.0-py3-none-any.wheel"), # Incorrect file extension (`.wheel`) ("foo__bar-1.0-py3-none-any.whl"), # Invalid name (`__`) ("foo\n-1.0-py3-none-any.whl"), # Invalid name (`\n`) ("foo#bar-1.0-py3-none-any.whl"), # Invalid name (`#`) ("-1.0-py3-none-any.whl"), # Empty project name ("-1.0-200-py3-none-any.whl"), # Empty project name (with build number) ("foobar-1.x-py3-none-any.whl"), # Invalid version (`1.x`) # Build number doesn't start with a digit (`abc`) ("foo-1.0-abc-py3-none-any.whl"), ("foo-1.0-200-py3-none-any-junk.whl"), # Too many dashes (`-junk`) ("foo-1.0--none-any.whl"), # Empty interpreter component ("foo-1.0-py3-none-.whl"), # Empty platform component ("foo-1.0-py3.-none-any.whl"), # Empty member in a compressed tag set ("playlyfe-0.1.1-2.7.6-none-any.whl"), # Invalid interpreter components ], ) def test_parse_wheel_invalid_filename(filename: str) -> None: with pytest.raises(InvalidWheelFilename): parse_wheel_filename(filename) @pytest.mark.parametrize( "filename", [ "pyvirtualcam-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", "foo-1.0-py3.py2-none-any.whl", ], ) def test_parse_wheel_unsorted_tags_valid_by_default(filename: str) -> None: # Unsorted compressed tags should parse fine without validate_order parse_wheel_filename(filename) @pytest.mark.parametrize( "filename", [ "pyvirtualcam-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", "foo-1.0-py3.py2-none-any.whl", ], ) def test_parse_wheel_unsorted_tags_invalid_with_validate(filename: str) -> None: with pytest.raises(InvalidWheelFilename): parse_wheel_filename(filename, validate_order=True) @pytest.mark.parametrize( ("filename", "name", "version"), [("foo-1.0.tar.gz", "foo", Version("1.0")), ("foo-1.0.zip", "foo", Version("1.0"))], ) def test_parse_sdist_filename(filename: str, name: str, version: Version) -> None: assert parse_sdist_filename(filename) == (name, version) @pytest.mark.parametrize( ("filename"), [ ("foo-1.0.xz"), # Incorrect extension ("foo1.0.tar.gz"), # Missing separator ("foo-1.x.tar.gz"), # Invalid version ("-1.0.tar.gz"), # Empty project name ("-1.0.zip"), # Empty project name (zip) ], ) def test_parse_sdist_invalid_filename(filename: str) -> None: with pytest.raises(InvalidSdistFilename): parse_sdist_filename(filename)